词库分词被认为是最理想的中文分词算法。如:“我们是中国人”,效果为:“我们”、“中国人”。
常见的词典分词有:极易分词:MMAnalyzer和庖丁分词:PaodingAnalzyer
4.4.3.1 庖丁分词的步骤
1、导入IK Analyzer 2012FF_hf1.zip包
2、引入分词器的配置文件IKAnalyzer.cfg.xml(配置停用词和自定义扩展词), 放到类路径下(src下)
3、引入ext_stopword.dic文件(存放停用词),放置到类路径下 如果要新增停用词,只需换一行写便可。刷新下项目。 4、新建ext_dict.dic文件(存放自定义的扩展词),放置到类路径下
4.5 测试分词器的代码
//测试分词器的代码 public static void testAnalyer(Analyzer analyzer, String text)
throws IOException {
System.out.println(\当前使用的分词器:\ + analyzer.getClass().getSimpleName());
}
TokenStream tokenStream = analyzer.tokenStream(\,
new StringReader(text));
tokenStream.addAttribute(CharTermAttribute.class); tokenStream.reset();
while (tokenStream.incrementToken()) { }
CharTermAttribute charTermAttribute = tokenStream
.getAttribute(CharTermAttribute.class);
System.out.println(new
String(charTermAttribute.toString()));
5 lucene全文检索和数据库检索的区别
6 lucene全文检索的得分
1,相关度得分是在查询时根据查询条件实进计算出来的
2,如果索引库数据不变,查询条件不变,查出的文档得分也不变
我们可以人工干预得分。索引库中的数据都是在对象转化为document之后添加进去的,所以我们可以在转化这个步骤进行干预。
其中的boost权限值默认为1f,上图修改成了4f,则新添加的数据就会排在前面
通过改变文档Boost值来改变排序结果。Boost是指索引建立过程中,给整篇文档或者文档的某一特定属性设定的权值因子,在检索时,优先返回分数高的。通过Document对象的setBoost()方法和Field对象的setBoost()方法,可以分别为Document和Field指定Boost参数。不同在于前者对文档中每一个域都修改了参数,而后者只针对指定域进行修改。默认值为1F,一般不做修改。
百度也由此来干预显示结果排序!
排序结果还与点击率,网站代码优化等相关。
7 优化索引库
优化这个问题是比较纠结的,索引优化也是很费资源和时间的,但是优化索引也是提高检索速度的重要方法,因此需要好好权衡这一点。还有就是在lucene3.6后面的版本中lucene可以自动进行索引的优化,当索引的数目达到一定的量之后会自动进行索引的优化 .
注意:如果不手动优化索引,lucene会根据生成的索引文件的段数来判断,进而自己进行索引文件的合并和索引的优化等操作。 建议不要手动优化,因为优化索引是一个很废资源的过程。
7.1 合并索引库
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(
Version.LUCENE_44, new
StandardAnalyzer(Version.LUCENE_44));
// 创建索引库优化对象...
LogMergePolicy logMergePolicy = new LogByteSizeMergePolicy(); // 值越小,搜索的时候越快,创建索引的时候越慢 // 值越大,搜索的时候越慢,创建索引的时候越快。 logMergePolicy.setMergeFactor(3); // 设置segment最大合并文档(Document)数 // 值较小有利于追加索引的速度
// 值较大,适合批量建立索引和更快的搜索
logMergePolicy.setMaxMergeDocs(1000);
indexWriterConfig.setMergePolicy(logMergePolicy);
7.2 使用RAMDirectory
Lucene的API接口设计的比较通用,输入输出结构都很像数据库的表==>记录==>字段,所以很多传统的应用的文件、数据库等都可以比较方便的映射到Lucene的存储结构/接口中。总体上看:可以先把Lucene当成一个支持全文索引的数据库系统。
Lucene的索引存储位置使用的是一个接口(抽象类),也就可以实现各种各样的实际存储方式(实现类、子类),比如存到文件系统中,存在内存中、存在数据库中等等。Lucene提供了两个子类:FSDirectory与RAMDirectory。
1, FSDirectory:在文件系统中,是真实的文件夹与文件。
2, RAMDirectory:在内存中,是模拟的文件夹与文件。与FSDirectory相比:1
因为没有IO操作,所以速度快。2,因为在内存中,所以在程序退出后索引库数据就不存在了。
@Test
public void testRamDirectory() throws Exception {
// 创建索引目录
Directory fsDir = FSDirectory.open(new File(\)); // 通过此对象可将硬盘上的索引读到内存中,涉及io操作... IOContext context = new IOContext();
// 将磁盘中的索引加载到内存当中,以后每次操作索引的时候,直接操作内存中的索
引即可,不用操作硬盘 Directory ramDir = new RAMDirectory(fsDir, context); }
// 构造索引读取器
IndexReader indexReader = DirectoryReader.open(ramDir); IndexSearcher indexSearcher = new IndexSearcher(indexReader); Query query = new TermQuery(new Term(\, \)); TopDocs docs = indexSearcher.search(query, 10); System.out.println(docs.totalHits);
7.3 其他优化方式
1. 排除停用词方式:排除停用,被分词器过滤掉,词就不会建立索引,索引文件就会变小,
这样搜索的时候就会变快。
2. 索引数据分区存放:给索引归类,引入路由功能。 3. 通过查询条件进行优化
8 排序和过滤
这2个都是在搜索索引库的时候进行的。IndexSearcher.search();
8.1 排序
//排序
SortField field=new SortField(\, Type.INT); Sort sort=new Sort(); sort.setSort(field);
TopDocs topDocs=indexSearcher.search(query, 100 ,sort);
默认的是按照升序排序的,如果想按照降序排序则在SortField参数中加true。 SortField field=new SortField(\, Type.INT,true);
8.2 过滤
使用Filter可以对搜索结果进行过滤以获得更小范围的结果。使用Filter对性能的影响很大(有可能会使查询慢上百倍)。但也可使用相应的查询实现一样的效果。
// indexSearcher.search(query, n);
// indexSearcher.search(query, filter, n); // indexSearcher.search(query, filter, n, sort); //过滤
//1,需要哪个字段进行过滤 2,字段对应的最小值 3,字段对应的最大值
//4,是否包含最小值 5,是否包含最大值
Filter filter=NumericRangeFilter.newIntRange(\, 1, 10, true, true);
TopDocs topDocs=indexSearcher.search(query,filter, 100);