Добавление слов к фразе запроса должно фильтровать результаты в Lucene - PullRequest
0 голосов
/ 29 февраля 2012

Я собираюсь наградить +100 на этот вопрос, когда это возможно, даже если он уже получен и принят

Я использую Lucene 3.2, вот что у меня есть в моем индексе икод:

  • Более 10 полей для каждого проиндексированного документа.
  • OR операнд в фразе запроса (т. е. «мой поиск в lucene» означает «мой поиск ИЛИ lucene ИЛИ»).
  • MultiFieldQueryParser с Occur.SHOULD во всех полях.
  • Специальное поле по умолчанию , содержащее все остальные поля (как предлагается в этом решении Как это сделатьмультиполе - поиск фраз в Lucene? ).

Чего я пытаюсь достичь?Что-то вроде Google-подобного поиска, позвольте мне объяснить:

  • Поиск по всем полям
  • Забитые результаты (с повышением для определенных полей и т. Д.)
  • Добавление слов в фразу запроса должно filter results

Я рассматриваю все аспекты, кроме этого.У меня следующие проблемы:

  • Если я выполняю поиск только в поле default , содержащем все остальные поля, я не получаю хорошие результаты
  • Поисктолько с операндом AND я получаю слишком отфильтрованные результаты, получая только те, у которых в одном поле есть фраза запроса целом .
  • Поиск только с операндом ИЛИ прекрасно работает только с одним словом взапрос, но при добавлении большего количества слов к фразе запроса результаты значительно возрастают вместо того, чтобы фильтровать (как это делает Google).
  • Я не знаю какчтобы отфильтровать один запрос от другого

Это мой фактический вызов парсера запросов:

MultiFieldQueryParser.parse(
    Version.LUCENE_31,
    OrQueryWords, //query words separated with OR operand
    searchFields, //String[] searchFields; // all fields
    occurs, //Occur[] occurs; {Occur.SHOULD, Occur.SHOULD, etc..}
    getFullTextSession().getSearchFactory().getAnalyzer(Product.class)
);

toString() этого запроса выводит что-то вроде этого:

(field1:"word1 word2" (field1:word1 field1:word2)) (field2:"word1 word2" (...)) etc.

Сейчас я пытаюсь добавить поле default (поле, содержащее все остальные поля) со словами запроса, разделенными операндом AND и Occur.MUST:

MultiFieldQueryParser.parse(
    Version.LUCENE_31,
    AndQueryWords, //query words separated with AND operand
    new String[] {"defaultField"},
    new Occur[] {Occur.MUST},
    getFullTextSession().getSearchFactory().getAnalyzer(Product.class)
);

* * * toString() этого запроса печатает это:

+(default:"word1 word2" (+default:word1 +default:word2))

Как я могу пересечь оба запроса?Есть ли другое решение, чтобы достичь этого?

Ответы [ 2 ]

1 голос
/ 01 марта 2012

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

Пересечение двух запросов

Вы, кажется, довольны своим конъюнктивным запросом в наборе результатов полей по умолчанию и вашим дизъюнктивным запросом для всех полей. Вы можете получить лучшее из обоих миров, используя последний в качестве основного запроса и первый в качестве фильтра.

Например:

Query mainQuery, filterQuery;

BooleanQuery query = new BooleanQuery();

// add the main query for scoring
query.add(mainQuery, Occur.SHOULD);

// prevent the filter query to participate in the scoring
filter.setBoost(0);
// make the filter query required
query.add(filterQuery, Occur.MUST);

Минимум должен соответствовать пунктам

Если И-все предложения слишком ограничительны, а И-все предложения недостаточно ограничительны, то вы можете сделать что-то среднее между ними, задав минимальное количество предложений СЛЕДУЕТ, которые должны соответствовать , чтобы документ появляется в наборе результатов.

Тогда трудная часть состоит в том, чтобы найти правильную формулу для вычисления минимального количества предложений SHOULD, которые должны соответствовать для оптимального взаимодействия с пользователем.

Например, допустим, вы хотите, чтобы ceil из 3/4 предложений SHOULD совпадал. Начиная с запроса с двумя предложениями и добавляя предложения до 5 предложений, получим следующую эволюцию числа результатов.

  • 2 условия => ceil (2 * 3/4) = 2: все предложения должны совпадать
  • 3 условия => ceil (3 * 3/4) = 3: должны совпадать предложения 3/4 (требуются новые пункты, меньше результатов)
  • 4 term => ceil (4 * 3/4) = 3: должны совпадать предложения 3/4 (одно из предложений не является обязательным, больше результаты)
  • 5 терминов => ceil (5 * 3/4) = 4: 4/5 предложения должны совпадать (может быть, больше, может быть, меньше результатов, в зависимости от совпадения нового термина с 4 первыми)

В любом случае, с этой функцией единственный способ уменьшить количество результатов при увеличении количества предложений - это иметь чисто конъюнктивный запрос.

1 голос
/ 29 февраля 2012

Подход, который я использовал для решения аналогичной проблемы, основан на ограничении количества результатов по баллам.

К сожалению, Lucene не предоставляет такую ​​функцию из коробки, и они также препятствуют этому подходу (http://wiki.apache.org/lucene-java/ScoresAsPercentages). Основное беспокойство основано на том факте, что абсолютное значение оценки не имеет смысла.

Я использовал относительное значение оценки для фильтрации: я выбрал наивысшую оценку, затем вычислил минимальную принятую оценку (скажем, maxScore / 5) и оставил только те результаты, которые удовлетворяли этому критерию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...