Запрос Lucene - «Совпадение точно с одним из x, y, z» - PullRequest
5 голосов
/ 12 октября 2009

У меня есть индекс Lucene, который содержит документы с полем типа, это поле может принимать одно из трех значений: «статья», «форум» или «блог». Я хочу, чтобы пользователь мог выполнять поиск в этих типах (для каждого типа документа есть флажок)

Как создать запрос Lucene в зависимости от того, какие типы выбран пользователем?

Пара предварительных условий:

  • Если пользователь не выбирает один из типов, я хочу, чтобы нет результатов этого типа.
  • Ограничение поля типа не должно влиять на порядок результатов.

Для справки, если бы я написал это на SQL (для «поиска по блогам или форумам»), я написал бы:

SELECT * FROM Docs
WHERE [type] in ('blog', 'forum')

Ответы [ 3 ]

4 голосов
/ 13 октября 2009

Для справки, если кто-то еще сталкивался с этой проблемой, вот мое решение:

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

Я перевернул логику (то есть исключил типы, которые пользователь не выбрал), потому что, если вы этого не сделаете, упорядочение результатов будет потеряно. Я не уверен, почему, хотя ...! Это позор, поскольку он делает код менее понятным / поддерживаемым, но по крайней мере он работает!

3 голосов
/ 12 октября 2009

Добавить ограничения для отклонения документов, которые не были выбраны. Например, если проверена только «статья», ограничение будет

-(type:forum type:blog)
0 голосов
/ 12 октября 2009

Хотя предложение Эриксона кажется нормальным, вы можете использовать положительное ограничение AND для вашего поискового запроса, например, text:foo AND type:article для случая, когда была отмечена только «статья», или text:foo AND (type:article OR type:forum) для случая были проверены "article" и "forum".

...