Lucene文档
Lucene文档
全文检索是一种将文件中所有文本与检索项匹配的检索方法。它可以根据需要获得全文中有关章、节、段、句、词等信息。计算机程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时根据建立的索引查找,类似于通过字典的检索字表查字的过程。
Lucene使用中几个比较关键的地方,首先,Lucene会先用分词器Analyzer将一篇文章分成许多个词、短语等,储存到硬盘中某个位置,再对其进行搜索时不再通过数据库查询,而是直接搜索本地文件。
关于分词器:
private Analyzeranalyzer= new Analyzer(true);
这就是最简单的一个初始化分词器的方法,在实际使用中,可以根据实际情况对分词器进行自定义,设置参数,选择模式等,也可以上网找能满足自己需求的分词器,本demo提供的是IKAnalyzer,是一款中文分词器,这是一个介绍地址,https://blog.****.net/eguid_1/article/details/51908862 选择一个好的分词器很重要,分词如果不对,会影响到后来的检索。
下面开始正式第一步,生成检索
直接放方法,
public voidindexDoc(IndexWriter writer, Dto dto) throws Exception {
Document doc = new Document();
Iterator iters =dto.entrySet().iterator();
while(iters.hasNext()){
Map.Entry entry=(Entry)iters.next();
//迭代器遍历获取到相应的键值对
String valueString =entry.getValue() != null?entry.getValue().toString():"";
doc.add(newTextField(entry.getKey().toString(), valueString,Field.Store.YES));
//排序使用
doc.add(newBinaryDocValuesField(entry.getKey().toString(), newBytesRef(valueString.getBytes())));
}
if (writer.getConfig().getOpenMode() ==IndexWriterConfig.OpenMode.CREATE){
writer.addDocument(doc);
}else{
// writer.updateDocument(newTerm("path", t.getPath()), doc);
}
}
两个参数,先说IndexWriter,
String类型变量指的是,当前制作的索引文件的放置目录。这段代码中就用到了开篇中提到的分词器。
第二个参数Dto,此处只要是一个map就可以,里面放着从数据库中查出来的记录,按照字段制成索引。
第二步,查询索引
查询索引的参数比较复杂,下面一个一个的来说一下。
Directorydirectory
这个path同样是你要查找的索引的位置。
String []query_field你要检索的字段名集合
BooleanClause.Occur[] filed_flag
int pageNo, intpageSize 这两个参数是指在检索的时候,进行分页的操作,页号和每页个数,如果在实际的使用中不需要检索分页的话,此处需要处理一下。
String...queries 最后一个参数是指检索条件,这个检索条件一般是从界面上获取的用户输入的检索条件,在getResultPage方法中,首先是使用这个参数生成一个Query,这个Query是Lucene进行检索的一个关键。
到此一个比较完整的流程就基本完成了,从创建索引到检索,分词器等等。利用以上步骤就可以实现一个简单地Lucene检索。
在一些场景中还可能出现一旦数据库中数据发生变化,则在索引文件中对应的索引也应该发生变化,数据删掉则索引也应该删掉,新加一条记录就应当往索引对应的位置也新加一条记录,下面这段来简单介绍一下如何动态改变索引。
添加一条索引
跟上面的创建索引基本上是一样的,需要注意的就是在创建索引的时候有可能对不同库的索引放在了不同的文件夹里,那么在添加一条索引的时候,注意IndexWriter对象和Directory对象创建时的路径要给对。
删除一条索引
Id值指的是数据库中的主键id,当然也可以是已经制成索引的其中任何一个字段,但是一般为了确保唯一性,应该选择一个唯一值。
更新一条索引
Dto指的是新的这条数据,id指的是你要更改的原来的索引对应的id