【问题标题】:Lucene query - "Match exactly one of x, y, z"Lucene 查询 - “完全匹配 x、y、z 之一”
【发布时间】:2009-10-12 11:09:26
【问题描述】:

我有一个 Lucene 索引,其中包含具有“类型”字段的文档,该字段可以是“文章”、“论坛”或“博客”三个值之一。我希望用户能够在这些类型中进行搜索(每种文档类型都有一个复选框)

如何根据用户选择的类型创建 Lucene 查询?

几个先决条件是:

  • 如果用户没有选择其中一种类型,我希望该类型没有结果。
  • 结果的顺序不应受到限制类型字段的影响。

如果我用 SQL 写这个作为参考(用于“博客或论坛搜索”),我会写:

SELECT * FROM Docs
WHERE [type] in ('blog', 'forum')

【问题讨论】:

    标签: lucene lucene.net


    【解决方案1】:

    作为参考,如果其他人遇到这个问题,这是我的解决方案:

    IList<string> ALL_TYPES = new[] { "article", "blog", "forum" };
    string q = ...; // The user's search string
    IList<string> includeTypes = ...; // List of types to include
    Query searchQuery = parser.Parse(q);
    Query parentQuery = new BooleanQuery();
    parentQuery.Add(searchQuery, BooleanClause.Occur.SHOULD);
    // Invert the logic, exclude the other types
    foreach (var type in ALL_TYPES.Except(includeTypes))
    {
        query.Add(
            new TermQuery(new Term("type", type)),
            BooleanClause.Occur.MUST_NOT
        );
    }
    searchQuery = parentQuery;
    

    我颠倒了逻辑(即排除了用户没有选择的类型),因为如果你不这样做,结果的排序就会丢失。虽然我不知道为什么......!这是一种耻辱,因为它使代码不太清晰/可维护,但至少它有效!

    【讨论】:

      【解决方案2】:

      添加约束以拒绝未选择的文档。例如,如果仅选中“article”,则约束将是

      -(type:forum type:blog)
      

      【讨论】:

      • 这就是我最后所做的,虽然我使用了 API 而不是将其创建为字符串,如果您有兴趣,请查看我的回答。
      【解决方案3】:

      虽然 erickson 的建议看起来不错,但您可以在搜索词中使用正向约束 AND,例如 text:foo AND type:article 仅检查“文章”的情况, 或text:foo AND (type:article OR type:forum) 表示“文章”和“论坛”都被检查了。

      【讨论】:

      • 有趣的是,两个查询 "text:foo AND (type:article OR type:forum)" 和 "text:foo AND -type:blog" 没有给出相同的结果,第一个查询返回首先是博客,而第二个查询维护排序(即博客和文章是混合的)。知道为什么吗?
      • Lucene 没有“AND”运算符。它有 +(要求)和 -(禁止)运算符。
      • @erickson:我不敢苟同:例如incubator.apache.org/lucene.net/docs/2.1/…
      猜你喜欢
      • 2013-02-26
      • 1970-01-01
      • 2014-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-12
      • 2012-10-07
      相关资源
      最近更新 更多