SpanNearQuery позволяет находить термины, которые находятся на определенном расстоянии друг от друга.
Пример (от http://www.lucidimagination.com/blog/2009/07/18/the-spanquery/):
Скажем, мы хотим найти люцен в течение 5
положения дуга, с последующим дугом
Lucene (порядок имеет значение) - вы можете использовать
следующий SpanQuery:
new SpanNearQuery(new SpanQuery[] {
new SpanTermQuery(new Term(FIELD, "lucene")),
new SpanTermQuery(new Term(FIELD, "doug"))},
5,
true);
альтернативный текст http://www.lucidimagination.com/blog/wp-content/uploads/2009/07/spanquery-dia1.png
В этом примере текста Lucene находится в пределах
3 Дуга
Но для вашего примера единственное совпадение, которое я вижу, состоит в том, что и ваш запрос, и целевой документ имеют "cd" (и я предполагаю, что все эти термины находятся в одном поле). В этом случае вам не нужно использовать какой-либо специальный тип запроса. Используя стандартные механизмы, вы получите ненулевой вес, основанный на том факте, что они оба содержат один и тот же термин в одном и том же поле.
Редактировать 3 - в ответ на последний комментарий ответ заключается в том, что вы не можете использовать SpanNearQuery
для выполнения чего-либо, кроме того, для чего он предназначен, то есть для выяснения, есть ли несколько терминов в Документы встречаются в определенном количестве мест друг друга. Я не могу сказать, каков ваш конкретный вариант использования / ожидаемые результаты (не стесняйтесь опубликовать его), но в последнем случае, если вы хотите узнать только, находится ли один или несколько из ("BAZ", "EXTRA") в документ, BooleanQuery
будет работать нормально.
Редактировать 4 - теперь, когда вы опубликовали свой вариант использования, я понимаю, что вы хотите сделать. Вот как вы можете это сделать: используйте BooleanQuery
, как упомянуто выше, чтобы объединить отдельные термины, которые вы хотите, а также SpanNearQuery
, и установите усиление на SpanNearQuery
.
Итак, запрос в текстовом виде будет выглядеть так:
BAZ OR EXTRA OR "BAZ EXTRA"~100^5
(в качестве примера - это будет соответствовать всем документам, содержащим либо «BAZ», либо «EXTRA», но назначать более высокий балл документам, в которых термины «BAZ» и «EXTRA» встречаются в пределах 100 мест друг от друга; корректируйте положение и увеличивайте, сколько хотите. Этот пример взят из поваренной книги Solr, поэтому он может не анализироваться в Lucene или может давать нежелательные результаты. Это нормально, потому что в следующем разделе я покажу вам, как создать это с помощью API).
Программно вы должны построить это следующим образом:
Query top = new BooleanQuery();
// Construct the terms since they will be used more than once
Term bazTerm = new Term("Field", "BAZ");
Term extraTerm = new Term("Field", "EXTRA");
// Add each term as "should" since we want a partial match
top.add(new TermQuery(bazTerm), BooleanClause.Occur.SHOULD);
top.add(new TermQuery(extraTerm), BooleanClause.Occur.SHOULD);
// Construct the SpanNearQuery, with slop 100 - a document will get a boost only
// if BAZ and EXTRA occur within 100 places of each other. The final parameter means
// that BAZ must occur before EXTRA.
SpanNearQuery spanQuery = new SpanNearQuery(
new SpanQuery[] { new SpanTermQuery(bazTerm),
new SpanTermQuery(extraTerm) },
100, true);
// Give it a boost of 5 since it is more important that the words are together
spanQuery.setBoost(5f);
// Add it as "should" since we want a match even when we don't have proximity
top.add(spanQuery, BooleanClause.Occur.SHOULD);
Надеюсь, это поможет! В будущем постарайтесь начать с публикации именно тех результатов, которые вы ожидаете - даже если это очевидно для вас, это может быть не так для читателя, а ясность может избежать необходимости повторяться туда и обратно столько раз.