【问题标题】:How can I use Lucene to search for documents that do not contain a term?如何使用 Lucene 搜索不包含术语的文档?
【发布时间】:2011-12-22 03:05:04
【问题描述】:

我知道Lucene documentation

注意:NOT 运算符不能只与一个术语一起使用。例如, 以下搜索将不返回任何结果:

不是“雅加达阿帕奇”

但是,我希望能够形成一个查询,该查询返回所有不包含术语的文档。我曾考虑将MatchAllDocsQueryTermQuery 串在一起成为BooleanQuery,但我似乎找不到合适的组合。

如果我索引以下两个文档

Doc0: content:The quick brown fox jumps over the lazy dog.
Doc1: (empty string)

当我只需要一个文档时,查询 *:* -content:fox 会返回两个文档。

this StackOverflow answer 建议的 RegexQuery content:^((?!fox).)*$ 返回一个文档,但它似乎无法正常工作,因为 content:^((?!foo).)*$ 在我期望它返回两个文档时也返回一个文档。

我知道我想做的事情对性能的影响。查询只会在几个文档上运行,所以我不太担心性能。

有没有办法编写一个 Lucene 查询来得到我想要的?

【问题讨论】:

    标签: java lucene


    【解决方案1】:

    您可以使用匹配所有内容并排除该术语 -

    IndexSearcher searcher = new IndexSearcher("path_to_index");
    MatchAllDocsQuery everyDocClause = new MatchAllDocsQuery();
    TermQuery termClause = new TermQuery(new Term("text", "exclude_term"));
    BooleanQuery query = new BooleanQuery();
    query.add(everyDocClause, BooleanClause.Occur.MUST);
    query.add(termClause, BooleanClause.Occur.MUST_NOT);
    Hits hits = searcher.search(query);  
    

    否则,有一个固定值的虚拟字段并使用查询

    +dummy_field:dummy_value -exclude_term
    

    【讨论】:

    • 你的两个答案都对我有用。 MatchAllDocsQuery 是首选。起初我实现了 MatchAllDocsQuery 但它没有用,所以我问了这个问题。当我让虚拟字段工作时,我切换回 MatchAllDocsQuery 进行健全性检查,它工作正常。我不确定为什么它以前对我不起作用。我一定是其中一个步骤出错了。
    【解决方案2】:

    你不能在每个文档中附加一个“人工”标记,然后搜索“'添加的标记'而不是'你想要避免的'”吗?

    【讨论】:

      猜你喜欢
      • 2011-05-28
      • 1970-01-01
      • 2014-03-13
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      相关资源
      最近更新 更多