【问题标题】:Lucene - "AND" sets of "OR" termsLucene - “AND”组“OR”术语
【发布时间】:2013-03-11 18:42:09
【问题描述】:

假设我使用列表国家等条件进行搜索。用户可以选择一组国家进行搜索,并将该组与其他条件相结合。

在 SQL 中,我会在 where 子句中执行此操作,即 WHERE (country = 'brazil' OR country = 'france' OR country = 'china) AND (其他搜索条件)。

尚不清楚如何在 Lucene 中执行此操作。 Query.combine 似乎很有希望,但如果我要处理多组“OR”术语,复杂性会很快增加。

Lucene 在这方面有能力吗?或者我应该使用这些类型的标准访问我的常规数据库并过滤我的 Lucene 结果?

深入挖掘,您似乎可以嵌套布尔查询来完成此操作。如果这种技术有效并且是否有效,我会更新答案。

【问题讨论】:

    标签: lucene lucene.net


    【解决方案1】:

    使用标准查询解析器(你可以看看relevant documentation),你可以使用类似于DB查询的语法,例如:

     (country:brazil OR country:france OR country:china) AND (other search criteria)
    

    或者,为了简化一点:

     country:(brazil OR france OR china) AND (other search criteria)
    

    另外,Lucene 还支持使用 +/- 而不是 AND/OR 语法编写的查询。我发现该语法对于 Lucene 查询更具表现力。这种形式的等价物是:

     +country:(brazil france china) +(other search criteria)
    

    如果手动构建查询,您确实可以嵌套BooleanQueries 以创建类似的结构,使用正确的BooleanClauses 来建立您指定的与/或逻辑:

    Query countryQuery = new BooleanQuery();
    countryQuery.add(new TermQuery(new Term("country","brazil")),BooleanClause.Occur.SHOULD);
    countryQuery.add(new TermQuery(new Term("country","france")),BooleanClause.Occur.SHOULD);
    countryQuery.add(new TermQuery(new Term("country","china")),BooleanClause.Occur.SHOULD);
    
    Query otherStuffQuery = //Set up the other query here, 
    //or get it from a query parser, or something
    
    Query rootQuery = new BooleanQuery();
    rootQuery.add(countryQuery, BooleanClause.Occur.MUST);
    rootQuery.add(otherStuffQuery, BooleanClause.Occur.MUST);
    

    【讨论】:

    • 感谢您的详细回复,非常好的分组文档链接。
    • 谢谢!这真的很有帮助。
    【解决方案2】:

    两种方式。

    1. 让 Lucene 制定查询。为此,请按以下格式发送查询字符串。

      查询:“国家(巴西法国中国)”

      内置的 QueryParser 使用 OR 运算符将上述字符串解析为 BooleanQuery。

    QueryParser qp = new QueryParser(Version.LUCENE_41, "country", new StandardAnalyzer(Version.LUCENE_41));
    Query q = qp.parse(s);
    
    1. 如果您想自己制定查询,
    BooleanQuery bq = new BooleanQuery();
    //
    TermQuery tq = new TermQuery(new Term("country", "brazil"));
    bq.add(tq, Occur.SHOULD); // SHOULD ==> OR operator
    //
    tq = new TermQuery(new Term("country", "france"));
    bq.add(tq, Occur.SHOULD);
    // 
    tq = new TermQuery(new Term("country", "china"));
    bq.add(tq, Occur.SHOULD);
    

    除非您添加数百个子查询,否则 Lucene 将在性能方面满足您的期望。

    【讨论】:

    • 我发现你是绝对正确的 - 即使是复杂的嵌套查询,Lucene 的速度也非常快。
    猜你喜欢
    • 2013-10-12
    • 1970-01-01
    • 2021-03-05
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    相关资源
    最近更新 更多