您现在的位置:首页 >> 技术架构 >> 搜索引擎 >> 内容

索引库管理

时间:2014-12-15 20:21:05

  核心提示:1.1.使用IndexDao提出问题:所有的数据(对象),我们都要存到数据库中。对于要进行搜索的数据,还要存到索引库中,以供搜索。一份数据同时存到数据库与索引库中(格式不同),就要想办法保证他们的状态...

1.1.使用IndexDao
提出问题:所有的数据(对象),我们都要存到数据库中。对于要进行搜索的数据,还要存到索引库中,以供搜索。一份数据同时存到数据库与索引库中(格式不同),就要想办法保证他们的状态一致。否则,就会影响搜索结果。

解决思路:对于上一段提出的问题:保证索引库中与数据库中的数据一致(只限要进行搜索的数据)。我们采用的方法是,在数据库中做了相应的操作后,在索引库中也做相应的操作。具体的索引库操作,是通过调用相应的IndexDao方法完成的,就如同使用数据库层的Dao。
我们目前只关注IndexDao中的每个方法的作用(怎么用起来方便就怎么设计)。现在不需要关心IndexDao的每个方法怎么实现,因为那是下一步的事情。
PublishAction.execute(){ // 发表文章
actionForm  article对象
articleDao.save( article ); // 保存到数据库
articleIndexDao.save( article ); // 保存到索引库
}
DeleteAction.execute(){ // 删除文章
articleDao.delete( id ); // 从数据库中删除
articleIndex.delete( id ); // 从索引库中删除
}
UpdateAction.execute(){ // 更新文章
actionForm  article对象
    articleDao.update( article ); // 更新数据库中的相应数据
    articleIndexDao.update( article ); // 更新索引库中的相应数据
}
1.2.数据与Document之间的转换
1.为什么要转换
我们在应用程序中使用对象表示数据。在数据库中使用的是表记录,不是对象,所以存在来回转换的问题。同样,要索引库中使用的是Document,也存在来回转换的问题。如下图:


2.怎么转换
对于一个要进行搜索的实体对象,我们会写一个对应的工具类,其中有两个方法:
1)Document Object2Document(Object object); // 对象Document
2)Object Document2Object(Document doc); // Document对象
在转换时,对象中的属性对应Document中的Field。由于Lucene只处理文本,所有所有的属性值在存储前都要先转成字符串。使用构造方法:Field(String name, String value, Store store, Index index)。
Store与Index都是枚举类型。Store:指定是否把当前属性值的原始内容存储到索引库中。如果存储,在搜索出相应数据时这个属性就有原始的值;如果不存储,得到的数据的这个属性的值为null。Index:指定是否建立索引(词汇表)。建立索引才能被搜索到。不可以不存储也不建立索引(没有意义)。
枚举类型 枚举常量 说明
Store  NO 不存储属性的值
 YES 存储把属性的值
Index NO 不建立索引
 ANALYZED 分词,建立索引
 NOT_ANALYZED 不分词,建立索引
  
  

// Store 指定当前字段的数据要不要存到索引库中
// Index 指定当前字段的数据是否可以被搜索(是否更新词汇表)

索引设置的一些建议:
1) 尽量减少不必要的存储
2) 不需要检索的内容不要建立索引
3) 非文本格式需要提前转化
4)需要整体存放的内容不要分词

NumericUtils与DateTools
如果属性的类型不是字符串,则要先进转换[对象转换器]:如果是数字类型,使用NumericUtils。如果是日期类型,则使用DataTools。
1.3.IndexWriter与建立、删除、更新索引
索引库的管理操作操作是通过类IndexWriter完成的。创建实例是使用构造方法:IndexWriter(Directory d, Analyzer a, MaxFieldLength mfl)。用完后要调用IndexWriter.close()方法释放资源。

1,建立索引:保存文档到索引库中。
a)把数据转成Document对象的形式。
b)调用方法IndexWriter.addDocument(Document doc)

2,删除索引:删除所有包含指定Term的文档。
a)生成用于确定要删除的文档的Term
b)调用方法IndexWriter.deleteDocuments(Term term)
说明:在生成Term时,一般。如果有多个文档含有指定的Term,则都会被删掉。

3,更新索引:实际执行的是先删除,后创建的操作。(参见前面的 索引文件的检索与维护)
a)把要更新后的对象转为Document对象
b)生成用于确定要更新的文档的Term
c)调用方法IndexWriter.updateDocument(Term term, Document doc)
说明:如果有多个文档含有指定的Term,更新后就只有一条记录(删掉所有,再创建一个)。如果没有文档含有指定的记录,不会报错,更新后有一条(新创建的)记录。
1.4.索引库对象Directory及相关操作
Lucene的API接口设计的比较通用,输入输出结构都很像数据库的表==>记录==>字段,所以很多传统的应用的文件、数据库等都可以比较方便的映射到Lucene的存储结构/接口中。总体上看:可以先把Lucene当成一个支持全文索引的数据库系统。
Lucene的索引存储位置使用的是一个接口(抽象类),也就可以实现各种各样的实际存储方式(实现类、子类),比如存到文件系统中,存在内存中、存在数据库中等等。Lucene提供了两个子类:FSDirectory与RAMDirectory。
1,FSDirectory:在文件系统中,是真实的文件夹与文件。
2,RAMDirectory:在内存中,是模拟的文件夹与文件。与FSDirectory相比:1因为没有IO操作,所以速度快。2,因为在内存中,所以在程序退出后索引库数据就不存在了。

索引库的相关操作:
1,合并索引库:Directory.addIndexes()
2,索引的优化:IndexWriter.optimize()
看看Compass中的Directory的子类,怎么存到数据库中的。

 

Java免费学习  Java自学网  http://www.javalearns.com

Tags:索引 管理 
作者:不详 来源:网络
    你是从哪里知道本网站的?
  • 网友介绍的
  • 百度搜索的
  • Google搜索的
  • 其它搜索过来的
  • 网址输错了进来的
  • 太忙了不记得了
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
本类推荐
  • 没有
本类固顶
  • 没有
  • java学习网(www.javalearns.com) © 2014 版权所有 All Rights Reserved.
  • Email:javalearns@163.com 站长QQ:1356121699 晋ICP备14003680号-3
  • java学习网部分内容来自网络或网友发布,如侵犯了您利益,请发邮件至:javalearns@126.com,我们尽快处理!
  • Java学习网
  • 网站统计
  • 晋公网安备 14042902000001号