Lucene:过滤不包含Term的文档

时间:2010-12-20 11:06:43

标签: java search filter lucene

我有一个索引,其文档有两个字段(实际上更像是800个字段,但其他字段在这里不关心我们):

  • contents字段包含文档的分析/标记化文本。在此字段中搜索查询字符串。
  • category字段包含文档的单个类别标识符。大约有2500个不同的类别,其中有几个类别可能会出现一个文档(即文档可能有多个category个条目。结果会被此字段过滤。

索引包含约20 mio。文件,大小为5 GB。

使用用户提供的查询字符串查询索引,以及用户感兴趣的几个类别的可选集合。问题是:怎么能我删除那些不仅匹配查询字符串而且还匹配不需要的类别的文档。

我可以使用带有BooleanQuery子句的MUST_NOT,例如:

BooleanQuery q = new BooleanQuery();
q.add(contentQuery, BooleanClause.MUST);
for (String unwanted: unwantedCategories) {
    q.add(new TermsQuery(new Term("category", unwanted), BooleanClause.MUST_NOT);
}

有没有办法用Lucene过滤器做到这一点?性能是一个问题,只有unwantedCategories的一些,反复出现的变体,所以CachingWrapperFilter可能会有很大帮助。此外,由于Lucene查询在现有代码库中的生成方式,很难将其纳入其中,而可以轻松引入额外的Filter

换句话说,如何根据必须 _not_在文档中出现的条款创建Filter

2 个答案:

答案 0 :(得分:7)

一个字的答案: BooleanFilter ,在制定问题后几分钟就找到了:

BooleanFilter f = new BooleanFilter();
for (String unwanted: unwantedCategories) {
    TermsFilter tf = new TermsFilter(new Term("category", unwanted));
    f.add(new FilterClause(tf, BooleanClause.MUST_NOT));
}

答案 1 :(得分:0)

您可以使用QueryWrapperFilter将任意查询转换为过滤器。您可以使用CachingWrapperFilter缓存任何过滤器。如下所示:

BooleanQuery bq = new BooleanQuery();
// set up bq
Filter myFilter = new CachingWrapperFilter (
                     new QueryWrapperFilter (bq)
                  );