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

Java 如何使用OR组合两个Lucene查询?,java,lucene,Java,Lucene,我想在两个名为“a”和“b”的字段上搜索我的索引。我得到了类似弗洛伊德——心理学理论的搜索,我想进行以下查询: (a="Freud" AND b="theories of psychology") OR (b="Freud" AND a="theories of psychology") 我该怎么做?到目前为止,我已经让Lucene使用MultiFieldQueryParser构建了两部分(firstHalf和secondHalf),然后我将它们与 BooleanQuery combined

我想在两个名为“a”和“b”的字段上搜索我的索引。我得到了类似弗洛伊德——心理学理论的搜索,我想进行以下查询:

(a="Freud" AND b="theories of psychology") OR (b="Freud" AND a="theories of psychology")
我该怎么做?到目前为止,我已经让Lucene使用
MultiFieldQueryParser
构建了两部分(
firstHalf
secondHalf
),然后我将它们与

BooleanQuery combined = new BooleanQuery();
combined.add(firstHalf, BooleanClause.Occur.SHOULD);
combined.add(secondHalf, BooleanClause.Occur.SHOULD);
但是,
combined
允许在只找到“理论”的地方返回结果,而不是在“心理学”的地方返回结果,在那里我肯定需要这两个术语。看起来Lucene把“心理学理论”分成了三个词,分别与OR结合起来。我如何防止这种情况

firstHalf
看起来像:

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
对象。

标准analyzer将标记化。因此,查询
心理学理论
等同于
理论或心理学

如果要搜索短语“心理学理论”,请使用,否则请注意,默认的QueryParser会将引号解释为短语的含义(即,将代码更改为
“\”心理学理论\


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

我自己发现了,但现在代码明显更长了;如果有人知道一个更优雅的解决方案,请发帖,我将很乐意奖励。:)(虽然我很快就会把它变成一个方法……但这是正在发生的事情的完整版本…)


事实证明,
应该
确实按照我需要的方式工作。希望有人会觉得这很有帮助,我不仅仅是在公共场合自言自语;)

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

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;
    }

}
例如:

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);            

刚刚被告知Lucene不支持这样的布尔逻辑,那应该是!=或在这种情况下,第二版《Lucene在行动》第95页是错误的现在我知道为什么我的查询被破坏了,只是不知道如何修复它。你确定查询是正确的吗?“心理理论”这个问题意味着这三个词中至少有一个必须出现在某个地方,但没有一个是必填词。@KaiChan没有,我不得不修改这个词来加入这个限制。不过我想我明白了。:)我最近的经验是,在学习Lucene时,应该避免使用QueryParser,并尝试将直接底层查询类型的所有内容组合在一起。您将更好地理解Lucene,并且不会因为查询语法而分心。正如Xodarap提到的,这里真正需要的是短语查询。你现在所拥有的将以任何顺序或位置与“心理学”的“理论”相匹配,而不是确切的短语。(事实上,StandardAnalyzer会过滤掉“of”,所以即使是短语查询也不会匹配您的确切短语……但这是我们通常只接受的搜索限制。)
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);