-
Lucene如何对搜索内容进行建模
-
Document是索引和搜索的原子单位
-
Document是包含一个或多个Field的容器,而Field中包含真正的被搜索内容
-
Lucene可以针对域Field进行3种操作
(1) 域值可以被索引
被索引的域值必须是文本格式,二进制格式的域值只能被存储不能被索引
(2) 域被索引后,可以选择性的存储项向量,后者可以视为该域的一个小型反向索引集合,通过该向量能够检索该域的所有语汇单元
(3) 域值可以被单独存储
-
当搜索程序通过索引搜索文档时,只有被存储的域才会被作为搜索结果呈现,被索引但未被存储的域不会被作为搜索结果呈现
-
Lucene和database的区别
(1) 灵活的架构
加入Index的每个Doc独立;
Doc中可以包含任意的域,任意的索引、存储和项向量;
可以随时对Doc进行索引,不必以前设计Doc的数据结构表;如果随后想向文档中添加域,可以完成添加后重新索引该文档或重建索引。
(2) 反向规格化
xml通过标记嵌套表示一个递归的文档结构,database靠join操作将多表连接。但是Lucene的Doc是单一的Doc,所以在创建对应的Lucene文档前,必须对上述递归文档结构和连接点进行反向规格化操作
-
-
理解索引过程
-
提取文本和创建文档
(1) 目标:从数据中提取纯文本格式信息
(2) 文档类型分类:
1° txt类
2° pdf, word类
3° xml, html类
(3) 可以结合Tika框架提取文本信息
-
分析文档
(1) 目标:将文本数据分割成语汇单元串,然后执行一些可选操作(例如统一大小写LowerCaseFilter、去掉频繁使用却无意义的词StopFilter、去掉词干PorterStemFilter等)
-
向索引Index添加文档Doc
(1) Lucene 将输入数据以倒排索引的数据结构进行存储
倒排索引用来回答的是“包含单词X的有哪些文档”(“倒排”的意思是正着想是一个文档包含哪些单词,倒着想是这个单词相关联的有哪些文档)
(2) Lucene 倒排索引的段结构
------> segment 0 | | segments_N ------> segment 1 | | ------> segment 2 | | .....
(3) Lucene索引包含一个或多个段;每个段都是一个独立的索引,包含整个文档索引的一个子集;
在搜索索引时,每个段都是单独访问的,然后将结果合并;
每个段包含多个文件,文件格式为 _X.<ext>,其中X代表段名称,<ext>代表扩展名,表示项向量、存储的域、倒排索引等;
如果使用混合文件格式(默认),那么上述所有文件会被压缩成一个文件:_X.cfs;
-
-
基本索引操作
-
向索引添加文档
addDocument(Document) addDocument(Document, Analyzer)
-
删除索引中的文档
deleteDocuments(Term) deleteDocuments(Term[]) deleteDocuments(Query) deleteDocuments(Query[]) deleteAll()
根据Term删除时,类似于数据库中的主键,这是Term的构造函数
public Term(String fld, String txt)
fld是键名,txt是键值,删除的是键名为键值的所有Doc;
为了确保通过Term删除可以成功,需要确认在每个文档中都已索引过对应的Field类,并且需要确认所有域值都是唯一的;
在创建该域时,该域需要被索引成未被分析的域,防止Analyzer将它分解为语汇单元
doc.add(new Field( "id", ids[i], Field.Store.YES, Field.Index.NOT_ANALYZED)); 其中,Field.Store.YES 和Field.Index.NOT_ANALYZED 都是Field的两个静态内部枚举类型Store和Index的实例
无论是添加Doc还是删除Doc,必须调用writer的commit()或close()方法向索引提交更改,否则会放在内存缓冲区。
-
更新索引中的文档
updateDocument(Term, Document); updateDocument(Term, Document, Analyzer);
Lucene无法做到只更新旧文档的某些Field,只能全部删除旧文档,然后添加新文档;
上面两个方法的语义是:删除包含Term的所有文档,然后添加Doc
-
-
未完待续……
chapter02_构建索引
最新推荐文章于 2024-09-23 19:28:37 发布