Lucene query - "Match exactly one of x, y, z"

I have a Lucene index that contains documents with a type field, this field can be one of three values ​​for article, forum, or blog. I want the user to be able to search in these types (there is a checkbox for each type of document)

How to create a Lucene query depending on what types the user has selected?

A couple of prerequisites:

  • If the user does not select one of the types, I want to get no from this type.
  • The ordering of the results should not be affected by the restriction of the type field.

For reference, if I wrote this in SQL (for searching a blog or forum), I would write:

SELECT * FROM Docs
WHERE [type] in ('blog', 'forum')
+5
source share
3 answers

For reference, if anyone else encounters this problem, here is my solution:

IList<string> ALL_TYPES = new[] { "article", "blog", "forum" };
string q = ...; // The user 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;

I inverted the logic (i.e., excluded types that the user did not select), because if you do not order the results, it is lost. I don’t know why, though ...! This is a shame as it makes the code less comprehensible / maintainable, but at least it works!

+4
source

Add restrictions to reject non-selected documents. For example, if only an “article” was checked, the restriction would be

-(type:forum type:blog)
+3
source

erickson , ANDed , text:foo AND type:article , "", text:foo AND (type:article OR type:forum) "", "".

0

All Articles