lucene的排序过滤和分页
2010-09-01 13:49
155 查看
三、排序过滤和分页
仅仅把东西搜出来是不够的,好的检索工具还应当能够对检索的结果进行排序,优先将最相关的内容送出
或是按照某种规则,将检索结果送出。
1.文档得分规则
文档得分主要是由4部分内容来决定,即tf(词条频率)、idf(反转文档频率)、boost(Field的激励因子)
和lengthNorm(长度因子)
tf:某个关键字在某文档中出现次数的平方根
idf:Math.log(numDocs/docFreq+1)+1.0 (numDocs:表示索引中总共的文档数量,docFreq:当前检索
的关键字的文档总数)
lengthNorm:在lucene的底层实现中,lengthNorm是一种固定值,它无需在索引时指定,只需要跟随创建
索引过程,被写入索引中。
boost:文档的boost值一般情况下默认为1.0,在建立索引时可通过预先人为的指定Document或Field的
boost值,来改变搜索时文档的得分,从而改变文档在搜索结果中的排序位置。
2.使用Sort排序
该类有6种构造函数
public Sort()
public Sort(String field) 默认为降序
public Sort(String field,boolean reverse)
public Sort(String[] fields)
public Sort(SortField field)
public Sort(SortField[] fields)
Sort可以对单一的Field进行排序,但是对多个Field的排序就必须要借助SortField类了。SortField类
是个包装类,它能描述Field和reverse(排序)信息,在搜索结果中有很多记录时,应该正确的指定Field
的类型,这样对排序过程的效率会有很大的提高。
排序有多种
a.按文档得分进行排序:这是lucene默认的排序方式
如:Hits hist=searcher.search(q,Sort.RELEVANCE); Sort.RELEVANCE表示当前的排序法则
是按照文档的得分进行降序排列
b.按文档的内部ID号来排序:在建立索引的时候,lucene会为每个文档建立一个内部的ID号
如:Hits hits=searcher.search(q,Sort.INDEXORDER) Sort.INDEXORDER表示排序法则是按
照文档的内部ID号来排序
c.按一个或多个Field来排序:把每个Field封装成SortField,然后以SortField[]数组的形式传入Sort类
注意:比较字符串时,Locale信息的不同,很有可能会影响到比较的结果,因此SortField类有这样的构
造函数,可以帮助指定Locale信息
public SortField(String field,Locale locale)
public SortField(String field,Locale locale,boolean reverse)
当指定Locale后,lucene才可以正确的对字符串进行比较,从而正确的排序。不过大多数情况下,使用Sort
进行排序时,排序的内容多为int型或是日期型。即便需要进行字符串的比较,也最好使用仅包含ASCII的
字符串Field进行,这样可以确保排序的正确,同时,尽量提高排序的效率。
3.搜索时使用过滤器
简单示例: Java代码
public class MySecurityFilter extends Filter{ public static final int SECURITY=0; public BitSet bits(IndexReader reader) throws IOException{ //先初始化一个BitSet对象 final BitSet bits=new BitSet(reader.maxDoc()); //将整个集合置为true,表示当前集合内的所有文档都是可以被检索到的 bits.set(0,bits.size()-1); //构造一个Term对象,代表最高安全级别 Term term=new Term("securitylevel",SECURITY+""); //从索引中取出具有最高安全级别的文档 TermDocs termDocs=reader.termDocs(term); //遍历每个文档 while(termDocs.next()){ bits.set(termDocs.doc(),false); } retrun bits; } }
或者:
Java代码
public class MySecurityFilter extends Filter{ public static final int SECURITY=0; public BitSet bits(IndexReader reader) throws IOException{ //先初始化一个BitSet对象 final BitSet bits=new BitSet(reader.maxDoc()); //将整个集合置为true,表示当前集合内的所有文档都是可以被检索到的
bits.set(0,bits.size()-1); //构造一个Term对象,代表最高安全级别
Term term=new Term("securitylevel",SECURITY+""); //初始化一个IndexSearcher对象
//查找securitylevel这个Field的值为SECURITY的文档
IndexSearcher searcher=new IndexSearcher(term); Hits hits=searcher.search(new TermQuery(term)); for(int i=0;i<hits.length();i++){ bits.set(hits.id(i),false); } retrun bits; } }
注意:Filter实际上在进行真正的查询之前,已经遍历过一次一遍索引了,因此无
论使用何种Filter,都不应该忽视它对查询效率的影响。
4.在结果中查询(QueryFilter)
在QueryFilter的bits方法中,调用IndexSearcher方法,对注入的Query进行一次
检索,然后在要被返回的BitSet中,将检索结果所对应的文档标记为true,即过滤掉了
所有不再检索结果范围内的文档。
仅仅把东西搜出来是不够的,好的检索工具还应当能够对检索的结果进行排序,优先将最相关的内容送出
或是按照某种规则,将检索结果送出。
1.文档得分规则
文档得分主要是由4部分内容来决定,即tf(词条频率)、idf(反转文档频率)、boost(Field的激励因子)
和lengthNorm(长度因子)
tf:某个关键字在某文档中出现次数的平方根
idf:Math.log(numDocs/docFreq+1)+1.0 (numDocs:表示索引中总共的文档数量,docFreq:当前检索
的关键字的文档总数)
lengthNorm:在lucene的底层实现中,lengthNorm是一种固定值,它无需在索引时指定,只需要跟随创建
索引过程,被写入索引中。
boost:文档的boost值一般情况下默认为1.0,在建立索引时可通过预先人为的指定Document或Field的
boost值,来改变搜索时文档的得分,从而改变文档在搜索结果中的排序位置。
2.使用Sort排序
该类有6种构造函数
public Sort()
public Sort(String field) 默认为降序
public Sort(String field,boolean reverse)
public Sort(String[] fields)
public Sort(SortField field)
public Sort(SortField[] fields)
Sort可以对单一的Field进行排序,但是对多个Field的排序就必须要借助SortField类了。SortField类
是个包装类,它能描述Field和reverse(排序)信息,在搜索结果中有很多记录时,应该正确的指定Field
的类型,这样对排序过程的效率会有很大的提高。
排序有多种
a.按文档得分进行排序:这是lucene默认的排序方式
如:Hits hist=searcher.search(q,Sort.RELEVANCE); Sort.RELEVANCE表示当前的排序法则
是按照文档的得分进行降序排列
b.按文档的内部ID号来排序:在建立索引的时候,lucene会为每个文档建立一个内部的ID号
如:Hits hits=searcher.search(q,Sort.INDEXORDER) Sort.INDEXORDER表示排序法则是按
照文档的内部ID号来排序
c.按一个或多个Field来排序:把每个Field封装成SortField,然后以SortField[]数组的形式传入Sort类
注意:比较字符串时,Locale信息的不同,很有可能会影响到比较的结果,因此SortField类有这样的构
造函数,可以帮助指定Locale信息
public SortField(String field,Locale locale)
public SortField(String field,Locale locale,boolean reverse)
当指定Locale后,lucene才可以正确的对字符串进行比较,从而正确的排序。不过大多数情况下,使用Sort
进行排序时,排序的内容多为int型或是日期型。即便需要进行字符串的比较,也最好使用仅包含ASCII的
字符串Field进行,这样可以确保排序的正确,同时,尽量提高排序的效率。
3.搜索时使用过滤器
简单示例: Java代码
public class MySecurityFilter extends Filter{ public static final int SECURITY=0; public BitSet bits(IndexReader reader) throws IOException{ //先初始化一个BitSet对象 final BitSet bits=new BitSet(reader.maxDoc()); //将整个集合置为true,表示当前集合内的所有文档都是可以被检索到的 bits.set(0,bits.size()-1); //构造一个Term对象,代表最高安全级别 Term term=new Term("securitylevel",SECURITY+""); //从索引中取出具有最高安全级别的文档 TermDocs termDocs=reader.termDocs(term); //遍历每个文档 while(termDocs.next()){ bits.set(termDocs.doc(),false); } retrun bits; } }
public class MySecurityFilter extends Filter{ public static final int SECURITY=0; public BitSet bits(IndexReader reader) throws IOException{ //先初始化一个BitSet对象 final BitSet bits=new BitSet(reader.maxDoc()); //将整个集合置为true,表示当前集合内的所有文档都是可以被检索到的 bits.set(0,bits.size()-1); //构造一个Term对象,代表最高安全级别 Term term=new Term("securitylevel",SECURITY+""); //从索引中取出具有最高安全级别的文档 TermDocs termDocs=reader.termDocs(term); //遍历每个文档 while(termDocs.next()){ bits.set(termDocs.doc(),false); } retrun bits; } }
或者:
Java代码
public class MySecurityFilter extends Filter{ public static final int SECURITY=0; public BitSet bits(IndexReader reader) throws IOException{ //先初始化一个BitSet对象 final BitSet bits=new BitSet(reader.maxDoc()); //将整个集合置为true,表示当前集合内的所有文档都是可以被检索到的
bits.set(0,bits.size()-1); //构造一个Term对象,代表最高安全级别
Term term=new Term("securitylevel",SECURITY+""); //初始化一个IndexSearcher对象
//查找securitylevel这个Field的值为SECURITY的文档
IndexSearcher searcher=new IndexSearcher(term); Hits hits=searcher.search(new TermQuery(term)); for(int i=0;i<hits.length();i++){ bits.set(hits.id(i),false); } retrun bits; } }
public class MySecurityFilter extends Filter{ public static final int SECURITY=0; public BitSet bits(IndexReader reader) throws IOException{ //先初始化一个BitSet对象 final BitSet bits=new BitSet(reader.maxDoc()); //将整个集合置为true,表示当前集合内的所有文档都是可以被检索到的 bits.set(0,bits.size()-1); //构造一个Term对象,代表最高安全级别 Term term=new Term("securitylevel",SECURITY+""); //初始化一个IndexSearcher对象 //查找securitylevel这个Field的值为SECURITY的文档 IndexSearcher searcher=new IndexSearcher(term); Hits hits=searcher.search(new TermQuery(term)); for(int i=0;i<hits.length();i++){ bits.set(hits.id(i),false); } retrun bits; } }
注意:Filter实际上在进行真正的查询之前,已经遍历过一次一遍索引了,因此无
论使用何种Filter,都不应该忽视它对查询效率的影响。
4.在结果中查询(QueryFilter)
在QueryFilter的bits方法中,调用IndexSearcher方法,对注入的Query进行一次
检索,然后在要被返回的BitSet中,将检索结果所对应的文档标记为true,即过滤掉了
所有不再检索结果范围内的文档。
相关文章推荐
- lucene查询索引库、分页、过滤、排序、高亮
- lucene查询索引库、分页、过滤、排序、高亮
- SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎 .
- (转)SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎
- MVC中使用EF:排序,过滤,分页
- 使用EF6和MVC5实现一个简单的选课系统--排序、过滤和分页(3/12)
- [ECSide文档] ECSide基于数据库的分页、排序、过滤的实现
- Lucene高亮显示,排序,过滤
- SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎
- lucene的过滤和分页
- MVC5学习系列——排序、过滤、分页
- DataTables+BootStrap组合使用Ajax来获取数据并且动态加载dom的方法(排序,过滤,分页等)
- EF6 学习笔记(三):排序、过滤查询及分页
- lucene 排序 分页
- 【EF6学习笔记】(三)排序、过滤查询及分页
- 【EntityFramework系列教程三,翻译】在ASP.NET MVC程序中使用EntityFramework对数据进行排序、过滤筛选以及实现分页
- 全文检索Lucene(三)----查询,分词器,排序,过滤,高亮
- lucene整理3 -- 排序、过滤、分词器
- Lucene 3.6.1:中文分词、创建索引库、排序、多字段分页查询以及高亮显示
- ECSide基于数据库的分页、排序、过滤的实现