首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用OR组合两个Lucene查询?

如何使用OR组合两个Lucene查询?
EN

Stack Overflow用户
提问于 2011-11-24 01:50:33
回答 3查看 12.6K关注 0票数 6

我想在名为"a“和"b”的两个字段上搜索我的索引。我得到了像Freud -- theories of psychology这样的搜索,我想执行以下查询:

代码语言:javascript
运行
复制
(a="Freud" AND b="theories of psychology") OR (b="Freud" AND a="theories of psychology")

我该怎么做呢?到目前为止,我让Lucene使用MultiFieldQueryParser构建了两个部分(firstHalfsecondHalf),然后我将它们与

代码语言:javascript
运行
复制
BooleanQuery combined = new BooleanQuery();
combined.add(firstHalf, BooleanClause.Occur.SHOULD);
combined.add(secondHalf, BooleanClause.Occur.SHOULD);

但是combined允许在只找到“理论”而不是“心理学”的地方返回结果,而我肯定想要这两个词。看起来Lucene正在将“心理学理论”分成三个单词,并将它们分别与OR组合在一起。我如何防止这种情况发生?

firstHalf看起来像这样:

代码语言:javascript
运行
复制
Query firstHalf = MultiFieldQueryParser.parse(Version.LUCENE_33,
         new String[]{"Freud", "theories of psychology"},
         new String[]{"a", "b"},
         new BooleanClause.Occur[]{BooleanClause.Occur.MUST, BooleanClause.Occur.MUST},
         analyzer);

其中analyzer只是一个StandardAnalyzer对象。

EN

回答 3

Stack Overflow用户

发布于 2011-11-29 04:10:30

我自己想出来了,但现在代码明显变长了;如果有人知道更优雅的解决方案,请张贴,我很乐意奖励。:) (尽管我将把它变成一个方法shortly...but,但这里是所发生的事情的完整版本...)

代码语言:javascript
运行
复制
QueryParser parser = new QueryParser(Version.LUCENE_33, "a", analyzer);
parser.setDefaultOperator(QueryParser.AND_OPERATOR);
Query a_0 = parser.parse("Freud");
parser = new QueryParser(Version.LUCENE_33, "b", analyzer);
parser.setDefaultOperator(QueryParser.AND_OPERATOR);
Query b_1 = parser.parse("theories of psychology");

BooleanQuery firstHalf = new BooleanQuery();
firstHalf.add(a_0, BooleanClause.Occur.MUST);
firstHalf.add(b_1, BooleanClause.Occur.MUST);

parser = new QueryParser(Version.LUCENE_33, "b", analyzer);
parser.setDefaultOperator(QueryParser.AND_OPERATOR);
Query b_0 = parser.parse("Freud");
parser = new QueryParser(Version.LUCENE_33, "a", analyzer);
parser.setDefaultOperator(QueryParser.AND_OPERATOR);
Query a_1 = parser.parse("theories of psychology");

BooleanQuery secondHalf = new BooleanQuery();
secondHalf.add(b_0, BooleanClause.Occur.MUST);
secondHalf.add(a_1, BooleanClause.Occur.MUST);

BooleanQuery combined = new BooleanQuery();
combined.add(firstHalf, BooleanClause.Occur.SHOULD);
combined.add(secondHalf, BooleanClause.Occur.SHOULD);

事实证明,SHOULD确实按照我需要的方式在这里工作。希望有人发现这对我有帮助,我不仅仅是在公共场合自言自语;)

票数 5
EN

Stack Overflow用户

发布于 2011-11-24 06:13:14

标准分析器将进行标记化。因此,查询theories of psychology等同于theories OR of OR psychology

如果你想搜索短语“心理学理论”,使用PhraseQuery,或者注意默认的QueryParser会将引号解释为一个短语的意思(例如,将你的代码改为"\"theories of psychology\"")。

是的,Lucene在某种意义上没有使用布尔逻辑,但它是技术上的,在这里并不是真正相关。

票数 2
EN

Stack Overflow用户

发布于 2013-05-30 17:34:53

我写了下面的类来生成链式模糊查询,其中一个术语必须在多个字段中进行搜索。可以通过调用GetQuery()方法来检索组合查询。

代码语言:javascript
运行
复制
public class QueryParam
{
    public string[] Fields { get; set; }
    public string Term { get; set; }

    private QueryParam _andOperandSuffix;
    private QueryParam _orOperandSuffix;

    private readonly BooleanQuery _indexerQuery = new BooleanQuery();        

    public QueryParam(string term, params string[] fields)
    {
        Term = term;
        Fields = fields;
    }

    public QueryParam And(QueryParam queryParam)
    {
        _andOperandSuffix = queryParam;
        return this;
    }

    public QueryParam Or(QueryParam queryParam)
    {
        _orOperandSuffix = queryParam;
        return this;
    }

    public BooleanQuery GetQuery()
    {            
        foreach (var field in Fields)
            _indexerQuery.Add(new FuzzyQuery(new Term(field, Term)), Occur.SHOULD);

        if (_andOperandSuffix != null)
            _indexerQuery.Add(_andOperandSuffix.GetQuery(),Occur.MUST);

        if (_orOperandSuffix != null)
            _indexerQuery.Add(_orOperandSuffix.GetQuery(), Occur.SHOULD);

        return _indexerQuery;
    }

}

示例:

代码语言:javascript
运行
复制
var leftquery = new QueryParam("Freud", "a").And(new QueryParam("theories of psychology", "b"));
var rightquery = new QueryParam("Freud", "b").And(new QueryParam("theories of psychology", "a"));
var query = leftquery.Or(rightquery);            
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8246790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档