2013-03-22 2 views
0

Предположим, у меня есть поиск по таким критериям, как список стран. Пользователь может выбрать набор стран для поиска и комбинировать этот набор с другими критериями.Lucene - «AND» наборы терминов «OR»

В SQL я бы сделал это в моем случае, то есть WHERE (страна = 'Бразилия) ИЛИ страна =' france 'ИЛИ страна =' china) И (другие критерии поиска).

Непонятно, как это сделать в Lucene. Query.combine, похоже, обещает, но это очень быстро увеличится, если у меня будет несколько наборов терминов «ИЛИ» для работы.

Является ли Lucene способным в этом отношении? Или я должен просто ударить свою обычную БД этими критериями и отфильтровать результаты Lucene?

Копаем глубже, похоже, вы можете вложить булевские запросы, чтобы выполнить это. Я обновлю ответ, если эта техника будет работать, и если она будет выполнена.

ответ

3

Используя стандартный анализатор запросов (и вы посмотрите на relevant documentation может), вы можете использовать синтаксис, подобный запрос БД, такие как:

(country:brazil OR country:france OR country:china) AND (other search criteria) 

Или, чтобы упростить немного:

country:(brazil OR france OR china) AND (other search criteria) 

В качестве альтернативы Lucene также поддерживает запросы, написанные с использованием +/-, а не синтаксиса AND/OR. Я нахожу этот синтаксис более выразительным для запроса Lucene. Эквивалент в этой форме будет:

+country:(brazil france china) +(other search criteria) 

Если вручную построения запросов, вы можете на самом деле гнездо BooleanQueries создать подобную структуру, используя правильный BooleanClauses установить и/или логики вы указываются:

Query countryQuery = new BooleanQuery(); 
countryQuery.add(new TermQuery(new Term("country","brazil")),BooleanClause.Occur.SHOULD); 
countryQuery.add(new TermQuery(new Term("country","france")),BooleanClause.Occur.SHOULD); 
countryQuery.add(new TermQuery(new Term("country","china")),BooleanClause.Occur.SHOULD); 

Query otherStuffQuery = //Set up the other query here, 
//or get it from a query parser, or something 

Query rootQuery = new BooleanQuery(); 
rootQuery.add(countryQuery, BooleanClause.Occur.MUST); 
rootQuery.add(otherStuffQuery, BooleanClause.Occur.MUST); 
+0

Спасибо за подробный ответ, отличную ссылку на документацию для группировки. – Kevin

+0

Спасибо! Это очень помогло. –

1

Два способа.

1) Позвольте Lucene сформулировать запрос. Для этого отправьте строку запроса в следующем формате.

Запрос: «страна (Бразилия Франция Китай)»

встроенный QueryParser разбирает выше строку в BooleanQuery с оператором ИЛИ.

QueryParser qp = new QueryParser(Version.LUCENE_41, "country", new StandardAnalyzer(Version.LUCENE_41)); 
    Query q = qp.parse(s); 

2) Если вы хотите, чтобы сформулировать то запрос самостоятельно,

BooleanQuery bq = new BooleanQuery(); 
    // 
    TermQuery tq = new TermQuery(new Term("country", "brazil")); 
    bq.add(tq, Occur.SHOULD); // SHOULD ==> OR operator 
    // 
    tq = new TermQuery(new Term("country", "france")); 
    bq.add(tq, Occur.SHOULD); 
    // 
    tq = new TermQuery(new Term("country", "china")); 
    bq.add(tq, Occur.SHOULD); 

Если вы не добавить сотни подзапросов, Lucene будет соответствовать вашим ожиданиям производительность мудрым.

+0

Я нашел, что вы абсолютно правы - Lucene невероятно быстро, даже со сложными вложенными запросами. – Kevin

Смежные вопросы