How to combine two Lucene queries using OR?

I would like to find my index in two fields called "a" and "b". I have been given queries such as Freud -- theories of psychology, and I would like to execute the following query:

(a="Freud" AND b="theories of psychology") OR (b="Freud" AND a="theories of psychology")

How should I do it? As long as I have Lucene creating two halves ( firstHalfand secondHalf) with help MultiFieldQueryParser, then I combined them with

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

But combinedit allows you to return results where only "theories" are found, not "psychology", where I definitely want both terms. It seems that Lutsen breaks down "theories of psychology" into three words and combines them individually with OR. How to prevent this?

firstHalf as follows:

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

where analyzeris just an object StandardAnalyzer.

+5
3

, ; - , , .:) ( ... , ...)

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

+3

. , theories of psychology theories OR of OR psychology.

" ", PhraseQuery , QueryParser (.. "\"theories of psychology\"").

, , Lucene , .

+2

I wrote a class below to generate chain fuzzy queries where you need to search in several fields. A combined request can be obtained by calling the method 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;
    }

}

Example:

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
source

All Articles