【问题标题】:Filtering Lucene result AND NOT过滤 Lucene 结果 AND NOT
【发布时间】:2014-05-20 23:41:54
【问题描述】:

我正在尝试从查询结果中过滤掉一些项目。

最终结果应仅包含 Private 设置为 false 或如果为 true,则属于提供的隐私组的结果

假设基本查询结果是这样的

ID  Name    Private PrivacyGroup
1   Yellow  false   
2   Red     true    1
3   Blue    true    2
4   Orange  true    1
5   Black   false
6   Green   true    3

我尝试了各种过滤器,但这似乎是我认为应该有效的过滤器,但它不是:

BooleanQuery bq = new BooleanQuery();       

BooleanQuery privacyQuery  = new BooleanQuery();
BooleanQuery privacyFinalQuery  = new BooleanQuery();

privacyFinalQuery.add(new TermQuery(new Term("Private", "true")),Occur.MUST);

for(String i : suppliedGroups){
privacyQuery.add(new TermQuery(new Term("PrivacyGroup", i)), Occur.SHOULD);
}

privacyFinalQuery.add(groupQuery, Occur.MUST_NOT);

bq.add(privacyFinalQuery, Occur.MUST_NOT);

return new CachingWrapperFilter(new QueryWrapperFilter(bq));

这导致

(-(+Private:true -(PrivacyGroup:1 PrivacyGroup:2)))

最终结果是 0 个结果,我期望:1,2,3,4,5

有什么建议吗?

【问题讨论】:

    标签: lucene


    【解决方案1】:

    您的查询是完全否定的,实际上与任何文档都不匹配。

    您应该添加MatchAllDocsQuery 作为第一个子句,并通过提供的否定查询进一步过滤它。

    尝试添加以下行:

    bq.add(new MatchAllDocsQuery(), Occur.MUST);
    

    【讨论】:

      【解决方案2】:

      MatchAllDocsQuery 开头的纯否定查询有效,是的。它的性能极差,但能胜任。

      似乎以与您陈述问题相同的方式构建查询会导致实现更简单,更少hacky:

      Private 设置为 false 或如果为 true,则属于提供的隐私组

      因此,您需要 private=false 或 group=1 或 group=2,可以更简单地说为:

      (Private:false PrivacyGroup:1 PrivacyGroup:2)
      

      或者,

      BooleanQuery privacyQuery  = new BooleanQuery();
      
      privacyQuery.add(new TermQuery(new Term("Private", "false")),Occur.SHOULD);
      
      for(String i : suppliedGroups){
          privacyQuery.add(new TermQuery(new Term("PrivacyGroup", i)), Occur.SHOULD);
      }
      
      return new CachingWrapperFilter(new QueryWrapperFilter(privacyQuery));
      

      【讨论】:

      • 是的,它是一个非常好的变体,但是 BQ 已经过适当优化,并且使用 advance 函数跳过了任何查询部分的大不匹配区域。所以我无法在没有测试的情况下进行性能差异估计。
      • @Nikolay 我不知道 lucene 中有任何性能优化可以使查询像 MatchAllDocsQuery -term 性能一样。您能指导我查看该功能的文档吗?
      • 一定有比使用 matchalldocsquery 更好的过滤内容的方法吗?我喜欢过滤方法,因为它保证了一定程度的安全性。如果我在查询过程中出现错误,我可以保证某些内容根本不会出现
      • 我相信我发布的代码会返回适当的过滤器,而不依赖于全部匹配。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-15
      相关资源
      最近更新 更多