Ответ 1
Различия между фразой и галькой в основном связаны с производительностью и скорингом.
При использовании фразовых запросов (например, "foo bar" ) в типичном случае, когда в индексе указаны одиночные слова, фразовые запросы должны пройти инвертированный индекс для "foo" и "bar" и найти документы, которые содержат оба термины, затем перейдите в свои списки позиций в каждом из этих документов, чтобы найти места, где "foo" появился прямо перед "баром".
Это имеет определенную стоимость как для производительности, так и для оценки:
- Позиции (.prx) должны быть проиндексированы и обысканы, это похоже на дополнительное "измерение" на инвертированный индекс, который увеличит индексирование и время поиска
- Поскольку в инвертированном индексе появляются только отдельные термины, нет реальной "фразы IDF", рассчитанной (это может не повлиять на вас). Таким образом, вместо этого это приближается на основе суммы термина IDF.
С другой стороны, если вы используете черепицу, вы также индексируете слово n-граммы, другими словами, если вы покалываете до размера 2, у вас также будут такие термины, как "foo bar" в индексе. Это означает, что для этого фразового запроса он будет анализироваться как простой TermQuery, без использования списков позиций. И поскольку теперь это "реальный термин", фраза IDF будет точной, потому что мы точно знаем, сколько документов этот "термин" существует.
Но использование черепицы также имеет некоторые издержки:
- Увеличенный словарь слов, индексный индекс и размер списков проводок, хотя это может быть справедливым компромиссом, особенно если вы полностью отключите позиции целиком с помощью Field.setIndexOptions.
- Некоторые дополнительные затраты на этапе анализа индексации: хотя ShingleFilter оптимизирован хорошо и довольно быстро.
- Нет очевидного способа вычислить "неряшливые фразовые запросы" или совпадения неточной фразы, хотя это можно приблизить, например. для фразы "foo bar baz" с черепицей размером 2, у вас будет два токена: foo_bar, bar_baz, и вы можете реализовать поиск через некоторые другие запросы lucene (например, BooleanQuery) для неточного приближения.
В общем, индексирование слов-nграмм с такими вещами, как Shingles или CommonGrams, - это просто компромисс (довольно экспертный), чтобы уменьшить стоимость позиционных запросов или улучшить фразу.
Но для этого есть реальные примеры использования, хороший пример доступен здесь: http://www.hathitrust.org/blogs/large-scale-search/slow-queries-and-common-words-part-2