【问题标题】:weird filter behavior in Lucene 5Lucene 5 中奇怪的过滤器行为
【发布时间】:2016-02-10 16:29:26
【问题描述】:

Lucene 5 中,Filter 已被弃用,取而代之的是 ConstantQuery 包装普通查询对象。我遇到了一个案例,旧过滤器对象中的“已翻译”查询对象无法按预期工作。

val directory = new RAMDirectory()
val config = new IndexWriterConfig(new KeywordAnalyzer())
val writer = new IndexWriter(directory, config)
writer.addDocument({
  val document = new Document()
  document.add(new StringField("k", "v1", Field.Store.YES))
  document.add(new StringField("k", "v2", Field.Store.YES))
  document
})
writer.addDocument({
  val document = new Document()
  document.add(new StringField("k", "v1", Field.Store.YES))
  document.add(new StringField("k", "v3", Field.Store.YES))
  document
})
writer.commit()

val reader = DirectoryReader.open(directory)
val searcher = new IndexSearcher(reader)

val filter =
  new BooleanQuery.Builder().add(
    new BooleanQuery.Builder()
      .add(new ConstantScoreQuery( new TermQuery( new Term("k", "v1") ) ), BooleanClause.Occur.MUST)
      .add(new ConstantScoreQuery( new TermQuery( new Term("k", "v2") ) ), BooleanClause.Occur.MUST_NOT)
      .build()
    ,
    BooleanClause.Occur.MUST_NOT
  ).build()

Console.println("filter: " + filter)
val results = searcher.search(filter, Int.MaxValue)
Console.println("# results: " + results.totalHits)

val filter2 = new BooleanFilter()

filter2.
  add({
    val inner = new BooleanFilter()
    inner add(new TermFilter(new Term("k", "v1")), BooleanClause.Occur.MUST)
    inner add(new TermFilter(new Term("k", "v2")), BooleanClause.Occur.MUST_NOT)
    inner
  }, BooleanClause.Occur.MUST_NOT)

Console.println("filter2: " + filter2)
val results2 = searcher.search(new MatchAllDocsQuery(), filter2, Int.MaxValue)
Console.println("# results2: " + results2.totalHits

控制台的输出是,

filter: -(+ConstantScore(k:v1) -ConstantScore(k:v2))
# results: 0
filter2: BooleanFilter(-BooleanFilter(+k:v1 -k:v2))
# results2: 1

从我的角度来看,我认为filterfilter2Lucene 5 中的工作方式应该相同,但显然结果并非如此。我做错了什么?

【问题讨论】:

    标签: lucene


    【解决方案1】:

    答案似乎来自这个 SO Post,

    Weird Solr/Lucene behaviors with boolean operators

    引用如下,

    布尔查询必须至少有一个“肯定”表达式(即;必须或应该)才能匹配。 Solr 试图帮助解决这个问题,如果被要求执行一个在最顶层只包含否定子句的 BooleanQuery,它会添加一个 match all docs 查询(即:*:*)

    如果顶层 BoolenQuery 在其内部某处包含一个仅包含否定子句的嵌套 BooleanQuery,则该嵌套查询将不会被修改,并且它(根据定义)与任何文档都不匹配——如果需要,这意味着外部查询将不匹配。

    简而言之,我想我必须在BooleanQuery.Builder 中添加一个MatchAllDocsQuery,以便至少有一个MUSTSHOULD 子句来使查询实际匹配某些内容(否则总是什么都不是)。 filter 修改如下即可。

    val filter =
      new BooleanQuery.Builder().add(
        new BooleanQuery.Builder()
          .add(new ConstantScoreQuery( new TermQuery( new Term("k", "v1") ) ), BooleanClause.Occur.MUST)
          .add(new ConstantScoreQuery( new TermQuery( new Term("k", "v2") ) ), BooleanClause.Occur.MUST_NOT)
          .build()
        ,
        BooleanClause.Occur.MUST_NOT
      ).add(new MatchAllDocsQuery(), BooleanClause.Occur.SHOULD).build()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      相关资源
      最近更新 更多