上QQ阅读APP看书,第一时间看更新
3.3.10 使用Filter筛选搜索结果
可以定义Filter类过滤查询结果,也可以缓存和重用Filter。如下条件可用Filter来实现:
● 根据不同的安全权限显示搜索结果。
● 仅查看上个月的数据。
● 在某个类别中查找,例如在分类统计查询中,根据分类列的有效取值缩小查询范围。
Filter返回一个DocIdSet,其中包含符合条件的文档编号。DocIdSet是一个存储文档编号的集合。例如:
IndexReader reader= … OpenBitSet bitSet = new OpenBitSet(reader.maxDoc()); // 假设所有的文档都不在集合内 bitSet.set( 0 ); //让第一个文档在集合内
Filter过滤整个索引,得到DocIdSet。
public abstract class Filter implements java.io.Serializable { public abstract DocIdSet getDocIdSet(IndexReader reader) throws IOException; }
下面定义一个BestDriversFilter,把搜索结果限定到score是5的司机。
public class BestDriversFilter extends Filter{ @Override public DocIdSet getDocIdSet(IndexReader reader) throws IOException { OpenBitSet bitSet = new OpenBitSet( reader.maxDoc() ); //查询出score是5的文档 TermDocs termDocs = reader.termDocs( new Term( "score", "5" ) ); while ( termDocs.next() ) { bitSet.set( termDocs.doc() ); // 把符合条件的文档对应的位置设为1 } return bitSet; } }
在查询中使用这个Filter:
Hits h = searcher.search(tq, filter);
完整的代码:
Filter bestDriversFilter = new BestDriversFilter(); //query不变,增加bestDriversFilter ScoreDoc[] hits = isearcher.search(query, bestDriversFilter, 10).scoreDocs; //因为不是每个司机都能得5分,所以返回的结果可能比以前少了