日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

lucene 入门整理

發(fā)布時(shí)間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lucene 入门整理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

1.??? 概述

Lucene是一個(gè)全文檢索引擎的架構(gòu),提供了完整的查詢(xún)引擎和索引引擎。Lucene以其方便使用、快速實(shí)施以及靈活性受到廣泛的關(guān)注。它可以方便地嵌入到各種應(yīng)用中實(shí)現(xiàn)針對(duì)應(yīng)用的全文索引、檢索功能,本總結(jié)使用lucene--2.3.2。

2.??? lucene?的包結(jié)構(gòu)

1、org.apache.lucene.analysis對(duì)需要建立索引的文本進(jìn)行分詞、過(guò)濾等操作, 語(yǔ)言分析器,主要用于的切詞Analyzer是一個(gè)抽象類(lèi),管理對(duì)文本內(nèi)容的切分詞規(guī)則。

2、org.apache.lucene.analysis.standard是標(biāo)準(zhǔn)分析器

3、org.apache.lucene.document提供對(duì)Document和Field的各種操作的支持。索引存儲(chǔ)時(shí)的文檔結(jié)構(gòu)管理,類(lèi)似于關(guān)系型數(shù)據(jù)庫(kù)的表結(jié)構(gòu)。Document相對(duì)于關(guān)系型數(shù)據(jù)庫(kù)的記錄對(duì)象,Field主要負(fù)責(zé)字段的管理。

4、org.apache.lucene.index是最重要的包,用于向Lucene提供建立索引時(shí)各種操作的支持。索引管理,包括索引建立、刪除等。索引包是整個(gè)系統(tǒng)核心,全文檢索的根本就是為每個(gè)切出來(lái)的詞建索引,查詢(xún)時(shí)就只需要遍歷索引,而不需要去正文中遍歷,從而極大的提高檢索效率。

5、org.apache.lucene.queryParser提供檢索時(shí)的分析支持。查詢(xún)分析器,實(shí)現(xiàn)查詢(xún)關(guān)鍵詞間的運(yùn)算,如與、或、非等。

6、org.apache.lucene.search 負(fù)責(zé)檢索。檢索管理,根據(jù)查詢(xún)條件,檢索得到結(jié)果。

7、org.apache.lucene.store提供對(duì)索引存儲(chǔ)的支持。數(shù)據(jù)存儲(chǔ)管理,主要包括一些底層的I/0操作。

8、org.apache.lucene.util提供一些常用工具類(lèi)和常量類(lèi)的支持

3.??? 索引文件格式

a)???????? .fnm格式? 包含了Document中所有field名稱(chēng)

b)??????? .fdt與.fdx格式? .fdt文件用于存儲(chǔ)具有Store.YES屬性的Field的數(shù)據(jù);.fdx是一個(gè)索引,用于存儲(chǔ)Document在.fdt中的位置。

c)???????? .tis 與.tii格式? .tis文件用于存儲(chǔ)分詞后的詞條(Term),而.tii就是它的索引文件,它表明了每個(gè).tis文件中的詞條的位置。

d)??????? deletable格式 文檔被刪除后,會(huì)首先在deletable文件中留下一個(gè)記錄,要真正刪除時(shí),才將索引除去。

e)???????? 復(fù)合索引格式 .cfs

使用IndexWriter的useCompoundFile()? 默認(rèn)為T(mén)rue

4.??? lucene中主要的類(lèi)

4.1. Document文檔類(lèi)

4.1.1.常用方法

方法

描述

void add(Field field)

Document對(duì)象中添加字段

void removeField(String name)

刪除字段。若多個(gè)字段以同一個(gè)字段名存在,則刪除首先添加的字段;若不存在,則Document保持不變

void removeFields(String name)

刪除所有字段。若字段不存在,則Document保持不變

Field getFieldString name

若多個(gè)字段以同一個(gè)字段名存在,則返回首先添加的字段;若字段不存在,則Document保持不變

Enumeration fields()

返回Document對(duì)象的所有字段,以枚舉類(lèi)型返回

Field [] getFields(String name)

根據(jù)名稱(chēng)得到一個(gè)Field的數(shù)組

String [] getValues(String name)

根據(jù)名稱(chēng)得到一個(gè)Field的值的數(shù)組

?

4.1.2.示例

Document doc1 = new Document();

doc1.add(new Field("name", "word1 word2 word3",

Field.Store.NO,Field.Index.TOKENIZED));

Document doc2 = new Document();

doc2.add(new Field("name", "word1 word2 word3",

Field.Store.NO,Field.Index.TOKENIZED));

4.2. Field字段類(lèi)

4.2.1.構(gòu)造方法

1)??????? public Field(String name,String value,Store store,Index index);//直接的字符串方式

2)??????? public Field(String name,String value,Store store,Index index,TermVector termVector);

3)??????? public Field(String name,String value,Reader reader);//使用Reader從外部傳入

4)??????? public Field(String name,String value,Reader reader,TermVector termVector);

5)??????? public Field(String name,byte[] value,Store store)//使用直接的二進(jìn)制byte傳入

當(dāng)Field值為二進(jìn)制時(shí),可以使用Lucene的壓縮功能將其值進(jìn)行壓縮。

4.2.2.Store類(lèi)

靜態(tài)屬性

描述

Store.NO

表示該Field不需要存儲(chǔ)

Store.YES

表示該Field需要存儲(chǔ)

Store.COMPRESS

表示用壓縮方式來(lái)保存這個(gè)Field的值

4.2.3.Index類(lèi)

靜態(tài)屬性

描述

Index.NO

不需要索引

Index.TOKENIZED

先被分詞再被索引

Index.UN_TOKENIZED

不對(duì)該Field進(jìn)行分詞,但會(huì)對(duì)它進(jìn)行索引

Index.NO_NORMS

對(duì)該Field進(jìn)行索引,但是不使用Analyzer,同時(shí)禁止它參加評(píng)分,主要是為了減少內(nèi)存的消耗。

?

4.2.4.示例

new Field("name", "word1 word2 word3",Field.Store.YES,Field.Index.TOKENIZED)

?

4.3. IndexWriter類(lèi)

4.3.1.構(gòu)造方法

1)??????? public IndexWriter(String path,Analyzer a,Boolean create)

2)??????? public IndexWriter(File path,Analyzer a,Boolean create)

3)??????? public IndexWriter(Directory d,Analyzer a,Boolean create)

第一個(gè)參數(shù):索引存放在什么地方

第二個(gè)參數(shù):分析器,繼承自org.apache.lucene.analysis.Analyzer類(lèi)

第三個(gè)參數(shù):為true時(shí),IndexWriter不管目錄內(nèi)是否已經(jīng)有索引了,一律清空,重新建立;當(dāng)為false時(shí),則IndexWriter會(huì)在原有基礎(chǔ)上增量添加索引。所以在更新的過(guò)程中,需要設(shè)置該值為false。

4.3.2.添加文檔

public void addDocument(Document doc)

public void addDocument(Document doc,Analyzer analyzer)//使用一個(gè)開(kāi)發(fā)者自定義的,而非事先在構(gòu)建IndexWriter時(shí)聲明的Analyzer來(lái)進(jìn)行分析

writer.addDocument(doc1);

4.3.3.性能參數(shù)

1)??????? mergeFactor控制Lucene在把索引從內(nèi)存寫(xiě)入磁盤(pán)上的文件系統(tǒng)時(shí)內(nèi)存中最大的Document數(shù)量,同時(shí)它還控制內(nèi)存中最大的Segment數(shù)量。默認(rèn)為10.

writer.setMergeFactor(10);

2)??????? maxMergeDocs限制一個(gè)Segment中最大的文檔數(shù)量。一個(gè)較大的maxMergeDocs適用于對(duì)大批量的文檔建立索引,增量式的索引則應(yīng)使用較小的maxMergeDocs。

writer.setMaxMergeDocs(1000);

3)??????? minMergeDocs用于控制內(nèi)存中持有的文檔數(shù)量的,它對(duì)磁盤(pán)上的Segment大小沒(méi)有任何影響。

4.3.4.限制Field的長(zhǎng)度

maxFieldLength限制Field的長(zhǎng)度,默認(rèn)值為10000.最大值100000個(gè)。

public void setMaxFieldLength(int maxFieldLength)

writer.addDocument(doc1);

writer.setMaxFieldLength(100000);

writer.addDocument(doc2);

4.3.5.復(fù)合索引格式

setUseCompoundFile(Boolean) 默認(rèn)true

writer.setUseCompoundFile(true);//復(fù)合索引

writer.setUseCompoundFile(false);

4.3.6.優(yōu)化索引

writer.optimize();

將磁盤(pán)上的多個(gè)segment進(jìn)行合并,組成一個(gè)全新的segment。這種方法并不會(huì)增加建索時(shí)的速度,反而會(huì)降低建索的速度。所以應(yīng)該在建完索引后在調(diào)用這個(gè)函數(shù)

4.3.7.示例

IndexWriter writer = new IndexWriter(path, new StandardAnalyzer(), true);

writer.addDocument(doc1);

writer.addDocument(doc2);

Sytem.out.println(writer.docCount());

writer.close();

IndexSearcher searcher = new IndexSearcher(path);

Hits hits = null;

Query query = null;

QueryParser parser =new QueryParser("name", new StandardAnalyzer());

query =parser.parse("word1");

hits = searcher.search(query);

System.out.println("查找 word1 共" + hits.length() + "個(gè)結(jié)果");

?

4.4. Directory類(lèi)

Directory:用于索引的存放位置

a)???????? FSDirectory.getDirectory(path, true)第二個(gè)參數(shù)表示刪除掉目錄內(nèi)原有內(nèi)容

IndexWriter writer = new IndexWriter(FSDirectory.getDirectory(path, true), new StandardAnalyzer(), true);//刪除原有索引

FSDirectory fsDir=FSDirectory.getDirectory(path,true);

IndexWriter writer = new IndexWriter(fsDir, new StandardAnalyzer(), true);

b)??????? RAMDirectory在內(nèi)存中存放,讀取速度快,但程序一運(yùn)行結(jié)束,它的內(nèi)容就不存在了

RAMDirectory ramDir=new RAMDirectory();

IndexWriter writer = new IndexWriter(ramDir, new StandardAnalyzer(), true);

?

IndexWriter writer = new IndexWriter(new RAMDirectory(), new StandardAnalyzer(), true);

4.5. IndexReader類(lèi)

IndexReader類(lèi)――索引的讀取工具

4.5.1.刪除文檔

IndexReader reader=IndexReader.open(path);

reader.deleteDocument(0);//刪除第一個(gè)

reader.close();

4.5.2.反刪除

reader.undeleteAll();

4.5.3.按字段刪除

reader.deleteDocuments(new Term("name","word1"));

若要真正物理刪除,則只需使用IndexWriter對(duì)索引optimize一次即可!

4.5.4.示例

IndexReader reader=IndexReader.open(path);

?????????? for(int i=0;i<reader.numDocs();i++){

????????????? System.out.println(reader.document(i));

?????????? }

?????????? System.out.println("版本:"+reader.getVersion());

?????????? System.out.println("索引內(nèi)的文檔數(shù)量:"+reader.numDocs());

?????????? //reader.deleteDocuments(new Term("name","word1"));

?????????? Term term1=new Term("name","word1");

?????????? TermDocs docs=reader.termDocs(term1);

?????????? while(docs.next())

?????????? {

????????????? System.out.println("含有所查找的"+term1+"的Document的編號(hào)為"+docs.doc());

????????????? System.out.println("Term在文檔中的出現(xiàn)次數(shù)"+docs.freq());

?????????? }

?????????? reader.close();

?

4.6. IndexModifier類(lèi)

集成了IndexWriter的大部分功能和IndexReader中對(duì)索引刪除的功能 ------ Lucene2.0的新類(lèi)

?

4.6.1.示例

public static void main(String[] args) throws Exception {

?????? IndexModifier modifier=new IndexModifier("C:\\Q1",new StandardAnalyzer(),true);

?????? Document doc1=new Document();

?????? doc1.add(new Field("bookname","鋼鐵是怎樣煉成的",Field.Store.YES,Field.Index.TOKENIZED));

?????? Document doc2=new Document();

?????? doc2.add(new Field("bookname","山山水水",Field.Store.YES,Field.Index.TOKENIZED));

?????? modifier.addDocument(doc1);

?????? modifier.addDocument(doc2);

??????

?????? System.out.println(modifier.docCount());

?????? modifier.setUseCompoundFile(false);

?????? modifier.close();

??????

?????? IndexModifier mo=new IndexModifier("C:\\Q1",new StandardAnalyzer(),false);

?????? mo.deleteDocument(0);

?????? System.out.println(mo.docCount());

?????? mo.close();

??? }

?

4.7. IndexSearcher類(lèi)

4.7.1.構(gòu)造方法

IndexSearcher searcher = new IndexSearcher(String path);

IndexSearcher searcher = new IndexSearcher(Directory directory);

IndexSearcher searcher = new IndexSearcher(IndexReader r);

IndexSearcher searcher = new IndexSearcher(IndexReader r,Boolean closeReader);

IndexSearcher searcher = new IndexSearcher(path);

IndexSearcher searcher = new IndexSearcher(FSDirectory.getDirectory(path,false) );

4.7.2.search方法

//返回Hits對(duì)象

public Hits search(Query query)

public Hits search(Query query,Filter filter)

public Hits search(Query query,Sort sort)

public Hits search(Query query,Filter filter,Sort sort)

?

//檢索只返回得分最高的Document

public TopDocs search(Query query,Filter filter,int n)

public TopDocs search(Weight weight,Filter filter,int n)

public TopFieldDocs search(Weight weight,Filter filter,int n,Sort sort)

public TopFieldDocs search(Query query,Filter filter,int n,Sort sort)

?

//傳入HitCollector,將結(jié)果保存在HitCollector中

public void search(Query query,HitCollector results)

public void search(Query query,Filter filter,HitCollector results)

public void search(Weight weight,Filter filter,HitCollector results)

4.7.3.Searcher的explain方法

public Explaination explain(Query query,int doc)throws IOException

for(int i=0;i<hits.length()&&i<10;i++)

{

??? Document d=hits.doc(i);

??? System.out.println(i+" "+hits.score(i)+" "+d.get("contents"));

System.out.println(searcher.explain(query,hits.id(i)).toString());

}

4.7.4.示例

IndexSearcher searcher = new IndexSearcher(path);

Hits hits = null;

Query query = null;

?

QueryParser parser =new QueryParser("contents", new StandardAnalyzer());

?

query =parser.parse("11");

hits = searcher.search(query);

System.out.println("查找 word1 共" + hits.length() + "個(gè)結(jié)果");

?

for(int i=0;i<hits.length()&&i<10;i++)

{

??? Document d=hits.doc(i);

??? System.out.println(d+" "+i+" "+hits.score(i)+" "+d.get("contents"));

}

searcher.close();

4.8. Hits類(lèi)

4.8.1.概述

Hits類(lèi)――檢索結(jié)果

4.8.2.常用方法

?

?

方法名

描述

int length()

返回搜索到結(jié)果的總數(shù)量

Document doc(int i)

返回第i個(gè)文檔

int id(int i)

返回第i個(gè)文檔的內(nèi)部ID號(hào)

float score(int i)

返回第i個(gè)文檔的得分

Iterator iterator()

取得Hits集合的遍歷對(duì)象

4.8.3.示例

for(int i=0;i<hits.length()&&i<10;i++)

{

??? Document d=hits.doc(i);

??? System.out.println(d+" "+" "+hits.score(i)+" "+d.get("contents"));

System.out.println("文檔的內(nèi)部ID號(hào):" + hits.id(i));

}

4.9. QueryParser類(lèi)

4.9.1.改變默認(rèn)的布爾邏輯

?? 默認(rèn)為“或”關(guān)系

Query query = null;

QueryParser parser =new QueryParser("contents", new StandardAnalyzer());

query =parser.parse("hello world!");

System.out.println(query.toString());

?? 改變默認(rèn)布爾邏輯

Query query = null;

QueryParser parser =new QueryParser("contents", new StandardAnalyzer());

parser.setDefaultOperator(QueryParser.AND_OPERATOR);

query =parser.parse("hello world");//若world后加!會(huì)出錯(cuò)

System.out.println(query.toString());

?? AND OR NOT – 關(guān)鍵字

也可以不用改變默認(rèn)布爾邏輯,而直接讓用戶(hù)在輸入關(guān)鍵字時(shí)指定不同詞條間的布爾聯(lián)系。例如,用戶(hù)輸入 hello AND world? 必須為大寫(xiě)

邏輯與:AND (大寫(xiě))

邏輯或:OR? (大寫(xiě))

邏輯非:-?? 例如: hello - world

也可以是NOT? 例如: hello NOT world

4.9.2.不需要分詞

不進(jìn)行分詞,將其完整的作為一個(gè)詞條進(jìn)行處理,則需要在詞組的外面加上引號(hào)

String queryStr="\"God helps those who help themselves\"";

QueryParser parser = new QueryParser("bookname",new StandardAnalyzer());

parser.setDefaultOperator(QueryParser.AND_OPERATOR);

Query query=parser.parse(queryStr);

System.out.println(query.toString());

4.9.3.設(shè)置坡度值,支持FuzzyQuery

String queryStr="\"God helps those who help themselves\"~1";//設(shè)置坡度為1

QueryParser parser = new QueryParser("bookname",new StandardAnalyzer());

Query query=parser.parse(queryStr);

System.out.println(query.toString());

4.9.4.設(shè)置通配符,支持WildcardQuery

String queryStr="wor?"

QueryParser parser = new QueryParser("bookname",new StandardAnalyzer());

parser.setDefaultOperator(QueryParser.AND_OPERATOR);

Query query=parser.parse(queryStr);

System.out.println(query.toString());

4.9.5.查找指定的Field

String queryStr="linux publishdate:2006-09-01";

QueryParser parser = new QueryParser("bookname",new StandardAnalyzer());

parser.setDefaultOperator(QueryParser.AND_OPERATOR);

Query query=parser.parse(queryStr);

System.out.println(query.toString());

例如:要求用戶(hù)選擇某一方面的

QueryParser parser=new QueryParser("publishdate",

new StandardAnalyzer());

Query query=parser.parse(queryStr);

System.out.println(query.toString());

?

輸出結(jié)果為publishdate:[081xmghs0 TO 0boeetj3z]

因?yàn)榻⑺饕龝r(shí),如果按照日期表示的字符串來(lái)進(jìn)行索引,實(shí)際上比較的是字符串的字典順序。而首先將日期轉(zhuǎn)為以毫秒計(jì)算的時(shí)間后,則可以精確地比較兩個(gè)日期的大小了。于是,lucene提供DateTools工具,用來(lái)完成其內(nèi)部對(duì)時(shí)間的轉(zhuǎn)化和處理,將毫秒級(jí)的時(shí)間轉(zhuǎn)化為一個(gè)長(zhǎng)字符串來(lái)進(jìn)行表示,并進(jìn)行索引。所以,遇到日期型數(shù)據(jù)時(shí),最好用DateTools進(jìn)行轉(zhuǎn)換,再進(jìn)行索引!

4.9.7.現(xiàn)在還不支持SpanQuery

4.10.??????? MultiFieldQueryParser類(lèi)--多域搜索

//在不同的Field上進(jìn)行不同的查找

public static Query parse(String []queries,String[] fields,Analyzer analyzer)throws ParseException

?

//在不同的Field上進(jìn)行同一個(gè)查找,指定它們之間的布爾關(guān)系

public static Query parse(String query,String[] fields,BooleanClause.Occur[] flags,Analyzer analyzer) throws ParseException

?

//在不同的Field上進(jìn)行不同的查找,指定它們之間的布爾關(guān)系

public static Query parse(String []queries,String [] fields,BooleanClause.Occur[] flags,Analyzer analyzer)throws ParseException

String [] queries={"鋼", "[10 TO 20]"};

String[] fields={“bookname”,”price”};

BooleanClause.Occur[] clauses={BooleanClause.Occur.MUST,BooleanClause.Occur.MUST};

Query query=MultiFieldQueryParser.parse(queries,fields,clauses,new StandardAnalyzer());

System.out.println(query.toString());

?

4.11.??????? MultiSearcher類(lèi)--多個(gè)索引搜索

IndexSearcher searcher1=new IndexSearcher(path1);

IndexSearcher searcher2=new IndexSearcher(path2);

IndexSeacher [] searchers={searcher1,seacher2};

MultiSearcher searcher=new MultiSearcher(searchers);

Hits hits=searcher.search(query);

for(int i=0;i<hits.length();i++){

??? System.out.println(hits.doc(i));

}

4.12.??????? ParalellMultiSearcher類(lèi)---多線程搜索

IndexSearcher searcher1=new IndexSearcher(path1);

IndexSearcher searcher2=new IndexSearcher(path2);

IndexSearcher [] searchers={searcher1,searcher2};

ParallelMultiSearcher searcher=new ParallelMultiSearcher(searchers);

long start=System.currentTimeMillis();

Hits hits=searcher.search(query);

long end=System.currentTimeMillis();

System.out.println((end-start)+"ms");

5.??? 排序

5.1. Sort類(lèi)

public Sort()

public Sort(String field)

public Sort(String field,Boolean reverse)? //默認(rèn)為false,降序排序

public Sort(String[] fields)

public Sort(SortField field)

public Sort(SortField[] fields)

Sort sort=new Sort(“bookname”);按照“bookname“這個(gè)Field值進(jìn)行降序排序

Sort sort=new Sort(“bookname”,true) //升序排序

Sort sort=new Sort(new String[]{“bookNumber”,”bookname”,”publishdate”});按照三個(gè)Field進(jìn)行排序,但無(wú)法指定升序排序,所以用SortField

5.2. SortField類(lèi)

public SortField(String field)

public SortField(String field,Boolean reverse)

public SortField(String field,int type) //type表示當(dāng)前Field值的類(lèi)型

public SortField(String field,int type,boolean reverse)? //默認(rèn)為false,升序

Field值的類(lèi)型:SortField.STRING、SortField.INT、SortField.FLOAT

SortField sf1=new SortField(“bookNumber”,SortField.INT,false);

SortField sf2=new SortField(“bookname”,SortField.STRING,false);

5.3. 指定排序的法則

5.3.1.按照文檔的得分降序排序

Hits hits=searcher.search(query,Sort.RELEVANCE);

5.3.2.按文檔的內(nèi)部ID升序排序

Hits hits=searcher.search(query, Sort.INDEXORDER);

5.3.3.按照一個(gè)Field來(lái)排序

Sort sort=new Sort();

SortField sf=new SortField(“bookNumber”,SortField.INT,false);

sort.setSort(sf);

Hits hits=searcher.search(query,sort);

5.3.4.按照多個(gè)Field來(lái)排序

Sort sort=new Sort();

SortField sf1=new SortField(“bookNumber”,SortField.INT,false);//升序

SortField sf2=new SortField(“publishdate”,SortField.STRING,true);//降序

sort.setSort(new SortField[]{sf1,sf2});

Hits hits=searcher.search(query,sort);

5.3.5.改變SortField中的Locale信息

String str1=”我”; String str2=”你”;

Collator co1=Collator.getInstance(Locale.CHINA);

Collator co2=Collator.getInstance(Locale.JAPAN);

System.out.println(Locale.CHINA+”:”+co1.compare(str1,str2));

System.out.println(Locale.JAPAN+”:”+co2.compare(str1,str2));

輸出結(jié)果為:

zh_CN:1

ja_JP:-1

所以

public SortField(String field,Locale locale)

public SortField(String field,Locale locale,boolean reverse)

6.??? 過(guò)濾器

使用public Hits search(Query query,Filter filter)

(1)簡(jiǎn)單過(guò)濾

Hits hits=searcher.search(query,new AdvancedSecurityFilter());//過(guò)濾掉securitylevel為0的結(jié)果

(2)范圍過(guò)濾—RangeFilter

只顯示中間的

RangeFilter filter=new RangeFilter(“publishdate”,”1970-01-01”,”1998-12-31”,true,true”);

Hits hits=searcher.search(query,filter);

?

無(wú)上邊界

public static RangeFilter More(String fieldname,String lowerTerm)

?

無(wú)下邊界

public static RangeFilter Less(String fieldname,String upperTerm)

(3)在結(jié)果中查詢(xún)QueryFilter

RangeQuery q=new RangeQuery(new Term(“publicshdate”,”1970-01-01”),

new Term(“publishdate”,”1999-01-01”),true);

QueryFilter filter=new QueryFilter(q);

Hits hits=searcher.search(query,filter);

7.??? 分析器Analysis

7.1. 自帶分析器和過(guò)濾器

?? 標(biāo)準(zhǔn)過(guò)濾器:StandardAnalyzer

?? 大小寫(xiě)轉(zhuǎn)換器:LowerCaseFilter

?? 忽略詞過(guò)濾器:StopFilter

public StopFilter(TokenStream input,String [] stopWords)

public StopFilter(TokenStream in,String [] stopWords,boolean ignoreCase)

public StopFilter(TokenStream input,Set stopWords,boolean ignoreCase)

public StopFilter(TokenStream in, Set stopWords)

其中,參數(shù)TokenStream代表當(dāng)前正在進(jìn)行處理的流;String類(lèi)型的數(shù)組代表一個(gè)用數(shù)組表示的忽略詞集合;Set類(lèi)型的參數(shù)與String一樣,是用來(lái)表示忽略詞集合的;boolean表示當(dāng)與忽略詞集合中的詞進(jìn)行匹配時(shí),是否需要忽略大小寫(xiě)。

?? 長(zhǎng)度過(guò)濾器:LengthFilter

?? PerFieldAnalyzerWrapper

?? WhitespaceAnalyzer

String str="str1 str2 str3";

?????? StringReader reader=new StringReader(str);

?????? Analyzer anlyzer=new WhitespaceAnalyzer();

??????

?????? TokenStream ts=anlyzer.tokenStream("", reader);

?????? Token t=null;

?????? while( (t=ts.next())!=null ){

?????????? System.out.println(t.termText());

?????? }

7.2. 第三方過(guò)分析器

?? 單字分詞

?? 二分法:CJKAnalyzer、中科院ICTCLAS分詞、JE分詞

?? 詞典分詞

7.2.1.JE分詞用法

7.2.1.1.?? 示例

import jeasy.analysis.MMAnalyzer;

IndexWriter writer = new IndexWriter(INDEX_STORE_PATH, new MMAnalyzer()

, true);

String str=" Lucene是一個(gè)全文檢索引擎的架構(gòu),"+

?????????? "提供了完整的查詢(xún)引擎和索引引擎。Lucene以其方便使用、快" +

?????????? "速實(shí)施以及靈活性受到廣泛的關(guān)注。它可以方便地嵌入到各種應(yīng)用" +

?????????? "中實(shí)現(xiàn)針對(duì)應(yīng)用的全文索引、檢索功能,本總結(jié)使用lucene--2.3.2。";

?????? MMAnalyzer analyzer=new MMAnalyzer();

?????? try{

?????????? System.out.println(analyzer.segment(str, "|"));

?????? }

?????? catch(Exception e)

?????? {

?????????? e.printStackTrace();

?????? }

輸出結(jié)果:lucene|一個(gè)|全文|檢索|引擎|架構(gòu)|提供|完整|查詢(xún)|。。。。

7.2.1.2.?? 設(shè)定正向最大匹配的字?jǐn)?shù)

MMAnalyzer analyzer=new MMAnalyzer(4);

7.2.1.3.?? 添加新詞

MMAnalyzer.addWord(String word);

MMAnalyzer.addDictionary(Reader reader);

?

MMAnalyzer analyzer=new MMAnalyzer();

MMAnalyzer.addWord("邁克爾雷第");

?

8.??? 索引的合并

RAMDirectory RAMDir=new RAMDirectory();

IndexWriter writer = new IndexWriter(RAMDir, new StandardAnalyzer(), true);//刪除原有索引

IndexWriter writer2=new IndexWriter(FSDirectory.getDirectory(path,true),

new StandardAnalyzer(), true);

writer.addDocument(doc1);

writer2.addDocument(doc2);

writer.close();

writer2.addIndexes(new Directory[]{RAMDir});

writer2.close();

注意:在合并前一定要先關(guān)閉要加的索引器。

9.??? 各種Query

9.1. 概述

query.toString()查看原子查詢(xún)

9.2. 使用特定的分析器搜索

IndexSearcher searcher = new IndexSearcher(path );

Hits hits = null;

Query query = null;

QueryParser parser =new QueryParser("contents", new StandardAnalyzer());

query =parser.parse("11 aand hello");

hits=searcher.search(query); //查找 name:11 name:hello 共1個(gè)結(jié)果

System.out.println("查找 "+query.toString()+" 共" + hits.length() + "個(gè)結(jié)果");

9.3. 按詞條搜索—TermQuery

Query query = null;

query=new TermQuery(new Term("name","word1 aand"));

hits=searcher.search(query);// 查找 name:word1 aand 共0個(gè)結(jié)果

System.out.println("查找 "+query.toString()+" 共" + hits.length() + "個(gè)結(jié)果");

9.4. 按“與或”搜索—BooleanQuery

1.和: MUST與MUST_NOT

2.或: SHOULD與SHOULD

3.A與B的并集-B? MUST與MUST_NOT

Query query1=null;

Query query2=null;

BooleanQuery query=null;

query1=new TermQuery(new Term("name","word1"));

query2=new TermQuery(new Term("name","word2"));

query=new BooleanQuery();

query.add(query1,BooleanClause.Occur.MUST);

query.add(query2,BooleanClause.Occur.MUST_NOT);

9.5. 在某一范圍內(nèi)搜索—RangeQuery

Term beginTime=new Term("time","200001");

Term endTime=new Term("time","200005");

RangeQuery query=null;

query=new RangeQuery(beginTime,endTime,false);//不包含邊界值

9.6. 使用前綴搜索—PrefixQuery

Term pre1=new Term("name","wor");

PrefixQuery query=null;

query = new PrefixQuery(pre1);

9.7. 短語(yǔ)搜索—PhraseQuery

a)默認(rèn)坡度為0

PhraseQuery query = new PhraseQuery();

query.add(new Term(“bookname”,”鋼”));

query.add(new Term(“bookname”,”鐵”));

Hits hits=searcher.search(query); //搜索“鋼鐵”短語(yǔ),而非“鋼”和“鐵”

b)設(shè)置坡度,默認(rèn)為0

PhraseQuery query = new PhraseQuery();

query.add(new Term(“bookname”,”鋼”));

query.add(new Term(“bookname”,”鐵”));

query.setSlop(1);

Hits hits=searcher.search(query);//搜索“鋼鐵”或“鋼*鐵”中含一字

9.8. 多短語(yǔ)搜索—MultiPhraseQuery

a)

MultiPhraseQuery query=new MultiPhraseQuery();

//首先向其中加入要查找的短語(yǔ)的前綴

query.add(new Term(“bookname”,”鋼”));

//構(gòu)建3個(gè)Term,作為短語(yǔ)的后綴

Term t1=new Term(“bookname”,”鐵”);

Term t2=new Term(“bookname”,”和”);

Term t3=new Term(“bookname”,”要”);

//再向query中加入所有的后綴,與前綴一起,它們將組成3個(gè)短語(yǔ)

query.add(new Term[]{t1,t2,t3});

Hits hits=searcher.search(query);

for(int i=0;i<hits.length();i++)

??? System.out.println(hits.doc(i));

b)

MultiPhraseQuery query=new MultiPhraseQuery();

Term t1=new Term(“bookname”,”鋼”);

Term t2 = new Term(“bookname”,”和”);

query.add(new Term[]{t1,t2});

query.add(new Term(“bookname”,”鐵”));

c)

MultiPhraseQuery query=new MultiPhraseQuery();

Term t1=new Term(“bookname”,”鋼”);

Term t2 = new Term(“bookname”,”和”);

query.add(new Term[]{t1,t2});

query.add(new Term(“bookname”,”鐵”));

Term t3=new Term(“bookname”,”是”);

Term t4=new Term(“bookname”,”戰(zhàn)”);

query.add(new Term[]{t3,t4});

9.9. 模糊搜索—FuzzyQuery

使用的算法為levenshtein算法,在比較兩個(gè)字符串時(shí),將動(dòng)作分為3種:

l? 加一個(gè)字母

l? 刪一個(gè)字母

l? 改變一個(gè)字母

FuzzyQuery query=new FuzzyQuery(new Term(“content”,”work”));

?

public FuzzyQuery(Term term)

public FuzzyQuery(Term term,float minimumSimilarity)throws IllegalArgumentException

public FuzzyQuery(Term term,float minimumSimilarity,int prefixLength)throws IllegalArgumentException

其中minimumSimilarity為最小相似度,越小則文檔的數(shù)量越多。默認(rèn)為0.5.其值必須<1.0

FuzzyQuery query=new FuzzyQuery(new Term(“content”,”work”),0.1f);

其中prefixLength表示要有多少個(gè)前綴字母必須完全匹配

FuzzyQuery query=new FuzzyQuery(new Term(“content”,”work”),0.1f,1);

9.10.??????? 通配符搜索—WildcardQuery

* 表示0到多個(gè)字符

? 表示一個(gè)單一的字符

WildcardQuery query=new WildcardQuery(new Term(“content”,”?qq*”));

9.11.??????? 跨度搜索

9.11.1.????? SpanTermQuery

效果和TermQuery相同

SpanTermQuery query=new SpanTermQuery(new Term(“content”,”abc”));

9.11.2.????? SpanFirstQuery

從Field內(nèi)容的起始位置開(kāi)始,在一個(gè)固定的寬度內(nèi)查找所指定的詞條

SpanFirstQuery query=new SpanFirstQuery(new Term(“content”,”abc”),3);//是第3個(gè)word,不是byte

9.11.3.????? SpanNearQuery

SpanNearQuery相當(dāng)與PhaseQuery

SpanTermQuery people=new SpanTermQuery(new Term(“content”,”mary”));

SpanTermQuery how=new SpanTermQuery(new Term(“content”,”poor”));

SpanNearQuery query=new SpanNearQuery(new SpanQuery[]{people,how},3,false);

9.11.4.????? SpanOrQuery

把所有SpanQuery的結(jié)果合起來(lái)

SpanTermQuery s1=new SpanTermQuery(new Term(“content”,”aa”);

SpanTermQuery s2=new SpanTermQuery(new Term(“content”,”cc”);

SpanTermQuery s3=new SpanTermQuery(new Term(“content”,”gg”);

SpanTermQuery s4=new SpanTermQuery(new Term(“content”,”kk”);

SpanNearQuery query1=new SpanNearQuery(new SpanQuery[]{s1,s2},1,false);

SpanNearQuery query2=new SpanNearQuery(new SpanQuery[]{s3,s4},3,false);

SpanOrQuery query=new SpanOrQuery(new SpanQuery[]{query1,query2});

9.11.5.????? SpanNotQuery

從第1個(gè)SpanQuery的查詢(xún)結(jié)果中,去掉第2個(gè)SpanQuery的查詢(xún)結(jié)果

SpanTermQuery s1=new SpanTermQuery(new Term(“content”,”aa”);

SpanFirstQuery query1=new SpanFirstQuery(s1,3);

?

SpanTermQuery s3=new SpanTermQuery(new Term(“content”,”gg”);

SpanTermQuery s4=new SpanTermQuery(new Term(“content”,”kk”);

SpanNearQuery query2=new SpanNearQuery(new SpanQuery[]{s3,s4},4,false);

?

SpanNotQuery query=new SpanNotQuery(query1,query2);

9.12.??????? RegexQuery—正則表達(dá)式的查詢(xún)

String regex="http://[a-z]{1,3}\\.abc\\.com/.*";

?????? RegexQuery query=new RegexQuery(new Term("url",regex));

?

10.?? 評(píng)分機(jī)制

10.1.??????? 概述

通過(guò)searcher.explain(Query query, int doc)方法可以查看某個(gè)文檔的得分的具體構(gòu)成。

在Lucene中score簡(jiǎn)單說(shuō)是由 tf * idf * boost * lengthNorm計(jì)算得出的。

1)??????? tf:Term Frequency.詞條頻率,是查詢(xún)的詞在文檔中出現(xiàn)的次數(shù)的平方根

2)??????? idf:表示反轉(zhuǎn)文檔頻率,Math.log(numDocs/(double)(docFreq+1))+1.0?? docDocs表示當(dāng)前檢索的詞條的文檔總數(shù), numDocs表示索引中總共的文檔數(shù)量

3)??????? boost:激勵(lì)因子,可以通過(guò)setBoost方法設(shè)置,需要說(shuō)明的通過(guò)field和doc都可以設(shè)置,所設(shè)置的值會(huì)同時(shí)起作用 。默認(rèn)為1.boost的值是在索引建立的時(shí)候已經(jīng)寫(xiě)入了,而不像其他計(jì)算得分的因子是在查詢(xún)時(shí)實(shí)時(shí)得出的。因此,一旦boost值被寫(xiě)入,就不能修改它,除非重新建立文檔索引。

4)??????? lengthNorm:是由搜索的field的長(zhǎng)度決定了,越長(zhǎng)文檔的分值越低。

11.?? Lucene的索引“鎖”

1.??? write.lock

2.??? commit.lock

?

轉(zhuǎn)載于:https://my.oschina.net/lujian863/blog/152018

總結(jié)

以上是生活随笔為你收集整理的lucene 入门整理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。