Lucunce-了解下

Lucence

jar

    commons-io-2.4.jar

    IKAnalyzer2012FF_u1.jar

    junit-4.9.jar

    lucene-analyzers-common-4.10.3.jar

    lucene-core-4.10.3.jar

    lucene-queryparser-4.10.3.jar

流程:

1、创建索引并写入索引库中

publicclassIndexSearchTest {

// 存储文档对象,文档对象还总包含域

List<Document>docs = newArrayList<>();

@Test

publicvoidIndexCreateTest() throwsIOException {

Filedir= newFile("/home/lxj/文档/参考资料/searchsource");

for(Filef:dir.listFiles()){

    StringfileName= f.getName();

    StringfileContext= FileUtils.readFileToString(f);

    LongfileSize= FileUtils.sizeOf(f);

// 文档对象

Documentdoc= newDocument();

/*

* 第一个参数:域名

* 第二个参数:值

* 第三个参数:是否存储,Store.YESStore.NO

*/

TextFieldnameField= newTextField("fileName",fileName,Store.YES);

TextFieldcontextField= newTextField("fileContext",fileContext,Store.YES);

TextFieldsizeField= newTextField("fileSize",fileSize.toString(),Store.YES);

doc.add(nameField);

doc.add(contextField);

doc.add(sizeField);

docs.add(doc);

}

/*

* 将文档放入磁盘,并将文档的内容进行分词

* 标准分词器,对英文很好,中文,单个字就是一个词

*/

Analyzeranalyzer= newStandardAnalyzer();

// 指定索引和文档存储目录

Directorydirectory= FSDirectory.open(newFile("/home/lxj/luke/dic"));

// 创建写对象初始化对象

IndexWriterConfigconfig= newIndexWriterConfig(Version.LUCENE_4_10_3,analyzer);

// 创建索引写对象

IndexWriteriWriter= newIndexWriter(directory,config);

// j将文档加入索引和文档的写对象中

for(Documentd:docs){

iWriter.addDocument(d);

}

iWriter.commit();

iWriter.close();

}

}


luke的使用

控制台模式下

输入java-jar lukeall-4.10.3.jar ,然后在path下输入索引库的位置

索引库:放索引的文件夹,自行创建。
















filed:

document:文档

term:词元,lucence中最小的单位。

2、从索引库中读取相关的值

流程:

待完善。。。。。。

@Test

publicvoidtestSearch() throwsIOException, ParseException {

// 创建与写入相同的分词器

Analyzeranalyzer= newStandardAnalyzer();

// 创建查询对象,第一个是默认搜索域,第二是分词器

QueryParserqueryParser= newQueryParser("fileContext",analyzer);

// 查询语法域名:关键词相当于sql

Queryquery = queryParser.parse("fileName:apache");

// 指定索引库目录

Directorydir= FSDirectory.open(newFile("/home/lxj/luke/dic"));

// 创建索引读取对象

IndexReaderiReader= IndexReader.open(dir);

// 创建索引的搜索对象

IndexSearchersearcher= newIndexSearcher(iReader);

// 搜索,参数:第一个是查询语句对象,第二个指定显示多少条

TopDocs topDocs= searcher.search(query,10);

// 错搜索结果获取结果集

ScoreDoc[]scoredocs= topDocs.scoreDocs;

System.out.println("=-====一共查询到+"+topDocs.totalHits+"记录=====");

for(ScoreDocsd:scoredocs){

// 获取ID

intdocId= sd.doc;

// 通过ID获取对应的文档

Documentdoc= iReader.document(docId);

// 根据域名获取对应的值

System.out.println("=====fileName:"+doc.get("fileName"));

System.out.println("=====fileSize:"+doc.get("fileSize"));

}

iReader.close();

}


3、域的详细介绍

是否分词

分词的目的是为了索引

需要分词:文件名称,文件内容

不需要分词:不需要索引的域,分词后无意义的域不需要分词,比如身份证号。

是否索引

需要搜索的域一定要索引,

索引:文件名称、文件内容、身份证号、

不需要索引的:图片地址不需要创建索引,图片地址搜索无意义。

是否存储

是否存储看个人需要,存储就是document内容存入磁盘中。如果需要马上显示存入document中查询显示速度快,如果不是马上显示出来,则不存储,额外占用磁盘,不划算。



域的各种类型:

4、中文分词

StandardAnalyzer

单字分词:就是按照中文一个字一个字地进行分词。如:我爱中国
效果:

  • CJKAnalyzer

二分法分词:按两个字进行切分。如:我是中国人,效果:我是是中中国”“国人


上边两个分词器无法满足需求。

  • SmartChineseAnalyzer

对中文支持较好,但扩展性差,扩展词库,禁用词库和同义词库等不好处理


使用IK_Analyzer进行分词

// 创建索引库

Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));

// 创建写对象配置对象

IndexWriterConfigconfig= newIndexWriterConfig(Version.LUCENE_4_10_3,newIKAnalyzer());

// 创建写对象

IndexWriteriWriter = newIndexWriter(dir, config);

扩展词库和禁用词库

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPEpropertiesSYSTEM"http://java.sun.com/dtd/properties.dtd">

<properties>

<comment>IKAnalyzer 扩展配置</comment>

<!--用户可以在这里配置自己的扩展字典

<entrykey="ext_dict">ext.dic;</entry>

-->

<!--用户可以在这里配置自己的扩展停止词字典-->

<entrykey="ext_stopwords">stopword.dic;</entry>

</properties>

5、删除

@Test

publicvoidIndexDel() throwsIOException {

// 索引库

Directorydir= FSDirectory.open(newFile("/home/lxj/luke/dic"));

// 创建写对象

IndexWriterwriter= newIndexWriter(dir,newIndexWriterConfig(Version.LUCENE_4_10_3,newIKAnalyzer()));

// 删除所有

// writer.deleteAll();

// Term就是一个词,第一个参数:域名,第二个就是词的域中含有关键词的数据

writer.deleteDocuments(newTerm("fileName","apache"));

writer.commit();

writer.close();

}

6、使用TermQuery进行查询,相比

别的不变,之前使用QueryPaser进行查询,这种方式多了一个默认的搜索域。

publicvoidTermQuery() throwsIOException {

// 索引库

Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));

// reader对象

IndexReaderreader= IndexReader.open(dir);

// 创建seracher对象

IndexSearchersearcher= newIndexSearcher(reader);

// 创建TermQuery对象

org.apache.lucene.search.TermQueryteQuery= neworg.apache.lucene.search.TermQuery(newTerm("fileName","java"));

// 获取搜索集

TopDocstopdocs= searcher.search(teQuery,10);

// 获取结果接

ScoreDoc[]docs= topdocs.scoreDocs;

for(ScoreDocdoc:docs){

// doc是一个文件的ID

Document document= reader.document(doc.doc);

System.out.println(document.get("fileName"));

System.out.println(document.get("fileSize"));

}

}

7、使用数字范围查询

publicvoidNumericRangeQuery()throwsIOException {

// 索引库

Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));

// reader对象

IndexReaderreader= IndexReader.open(dir);

// 创建seracher对象

IndexSearchersearcher= newIndexSearcher(reader);

// 使用数值范围查询

Queryquery= org.apache.lucene.search.NumericRangeQuery.newLongRange("fileSize",100L, 1000L, true,true);

// 获取搜索集

TopDocstopdocs= searcher.search(query,10);

// 获取结果接

ScoreDoc[]docs= topdocs.scoreDocs;

for(ScoreDocdoc:docs){

// doc是一个文件的ID

Document document= reader.document(doc.doc);

System.out.println(document.get("fileName"));

System.out.println(document.get("fileSize"));

}

}


8、使用BooleanQuery进行多条件查询

// 索引库

Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));

// reader对象

IndexReaderreader= IndexReader.open(dir);

// 创建seracher对象

IndexSearchersearcher= newIndexSearcher(reader);

// 使用数值范围查询

Queryquery= org.apache.lucene.search.NumericRangeQuery.newLongRange("fileSize",100L, 2000L, true,true);

// 创建TermQuery对象

org.apache.lucene.search.TermQueryteQuery= neworg.apache.lucene.search.TermQuery(newTerm("fileName","java"));

// 组合查询文件中包含Java,文件大小在1001000之间的

org.apache.lucene.search.BooleanQuerybQuery= neworg.apache.lucene.search.BooleanQuery();

// Occur.MUST是并且的&o的意思should是或的意思, must_not是非的意思

bQuery.add(teQuery,Occur.MUST);

bQuery.add(query,Occur.MUST);

// 获取搜索集

TopDocstopdocs= searcher.search(bQuery,10);

// 获取结果接

ScoreDoc[]docs= topdocs.scoreDocs;

for(ScoreDocdoc:docs){

// doc是一个文件的ID

Document document= reader.document(doc.doc);

System.out.println(document.get("fileName"));

System.out.println(document.get("fileSize"));

}

}

@Test

publicvoidNumericRangeQuery() throwsIOException {

// 多个查询进行组合查询

// 索引库

Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));

// reader对象

IndexReaderreader= IndexReader.open(dir);

// 创建seracher对象

IndexSearchersearcher= newIndexSearcher(reader);

// 使用数值范围查询

Queryquery= org.apache.lucene.search.NumericRangeQuery.newLongRange("fileSize",100L, 2000L, true,true);

// 获取搜索集

TopDocstopdocs= searcher.search(query,10);

// 获取结果接

ScoreDoc[]docs= topdocs.scoreDocs;

for(ScoreDocdoc:docs){

// doc是一个文件的ID

Document document= reader.document(doc.doc);

System.out.println(document.get("fileName"));

System.out.println(document.get("fileSize"));

}

}

9MutiFieldsQuery查询

使用多个域进行查询

publicvoid MultiFieldQueryTest() throwsIOException, ParseException {

// 多个域查询

// 索引库

Directory dir= FSDirectory.open(newFile("/home/lxj/luke/dic"));

// reader对象

IndexReaderreader= IndexReader.open(dir);

// 创建seracher对象

IndexSearchersearcher= newIndexSearcher(reader);

// 使用数值范围查询

// Queryquery =org.apache.lucene.search.NumericRangeQuery.newLongRange("fileSize",100L, 2000L, true, true);

String[]fields= {"fileName","fileContent"};

MultiFieldQueryParsermultiquery= newMultiFieldQueryParser(fields,newIKAnalyzer());

Queryquery= multiquery.parse("apache");

// 获取搜索集

TopDocstopdocs= searcher.search(query,10);

// 获取结果接

ScoreDoc[]docs= topdocs.scoreDocs;

for(ScoreDocdoc:docs){

// doc是一个文件的ID

Document document= reader.document(doc.doc);

System.out.println(document.get("fileName"));

System.out.println(document.get("fileSize"));

}

}        

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章