Повторение проблемы
- Во-первых, взгляните на следующий пример и угадайте, могут ли два запроса вызвать doc1
PUT test_phrase
{
"mappings" : {
"_doc" : {
"properties" : {
"body" : {
"type" : "text",
"analyzer" : "ik_max_word",
"search_analyzer" : "ik_smart"
}
}
}
}
}
PUT test_phrase/_doc/1
{
"body":"南京市长"
}
GET test_phrase/_search
{
"query": {
"match_phrase": {
"body": "南京市长"
}
}
}
GET test_phrase/_search
{
"query": {
"match_phrase": {
"body": "南京"
}
}
}
- Результат показан ниже: «Мэр Нанкина» не может быть отозван, но «Нанкин» может быть отозван. ![](Дай мне, Али боится, что есть objects.com/in os/antoffeinc… =300x600)
Причина анализ
- Так почему? Во-первых, результаты двух психоболов различны, поэтому они прямо подозревают, что не могут найти проблемы, вызванные разными словами.
# GET test_phrase/_analyze
# {
# "text": ["南京市长"],
# "analyzer": "ik_max_word"
# }
{
"tokens" : [
{
"token" : "南京",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "南京市",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "市长",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 2
}
]
}
# GET test_phrase/_analyze
# {
# "text": ["南京市长"],
# "analyzer": "ik_smart"
# }
{
"tokens" : [
{
"token" : "南京",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "市长",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 1
}
]
}
- Так почему же возникает проблема из-за несоответствия в сегментации слов?
- Разобрав исходный код, мы видим, что общий процесс Phrase выглядит следующим образом.
- детали следующим образом
-
org.elasticsearch.index.query.MatchPhraseQueryBuilder#doToQuery
Получив запрос запроса, превратите его в фразовый запрос matchQuery. -
org.elasticsearch.index.search.MatchQuery#parse
Разобрать запрос и превратить его в запрос lucene
- в
org.elasticsearch.index.search.MatchQuery#getAnalyzer
Определение словного выключателя, если анализатор запроса не указан, то фраза в использовании поиска «поиск», если не поиска «отеализатор ».
-
org.apache.lucene.util.QueryBuilder#createFieldQuery
Выполните сегментацию слов и определите, есть ли графы и синонимы, если нет, используйте простой фразовый запрос -
org.apache.lucene.util.QueryBuilder#analyzePhrase
Создавайте реальные запросы и определяйте позицию каждого слова -
org.apache.lucene.search.PhraseWeight#getPhraseMatcher
Вспомните перевернутую цепочку, затем оцените отстой, если он равен 0, обратитесь к ExactPhraseMatcher -
org.apache.lucene.search.ExactPhraseMatcher#nextMatch
Сравните позиции на равенство
-
временное решение
- Из второго шага выше мы видим, что сам ES также предоставляет решение с использованием searchQuoteAnalyzer. Таким образом, временное решение может состоять в том, чтобы позволить пользователю добавлять в текстовое поле
search_quote_analyzer
параметр,официальная документация search_quote_analyzer - Кроме того, если это один сценарий, вы можете указать анализатор или quote_analyzer в строке запроса при запросе.
Решения и трудности
- Однако позволять пользователям вносить изменения не слишком элегантно, поэтому мы все еще надеемся найти решение на уровне движка. Однако лучшего решения пока не найдено, поэтому временно запишу идеи и внесу дополнения позже.
- Из вышеприведенного анализа видно, что суть этой проблемы в том, что PhraseQuery определяет, является ли оно коротким предложением, исходя из непрерывности позиции позиции, а из-за разных токенизаторов при записи и запросе позиции несовместимы.
- Поэтому есть две идеи, но обе они несколько трудны.Я также надеюсь, что мы сможем вам помочь.
Несколько позиций
- Идея: изменить логику генерации позиции, чтобы сделать запрос и запись согласованными. Например
ik_max_word
В режиме есть три метода сегментации, и позиция помечается отдельно вместо исходной смешанной метки, чтобы гарантировать, что smart также является подмножеством max - Возьмем в качестве примера «Техническое обслуживание моста через реку Янцзы в Нанкине».
-
Текущая смешанная схема ставок:
Нанкин Нанкин мэр Янцзы Мост через реку Янцзы мост ремонт 0 1 2 3 4 5 6 -
Независимая схема маркировки:
Нанкин Нанкин мэр Янцзы Мост через реку Янцзы мост ремонт 0 - 1 2 - 3 4 0 - 1 - 2 - 3 - 0 - 1 - 2 3 - 0 - - 1 - 2
-
- Трудности: Как видно из приведенного выше примера, хотя эта схема может обеспечить согласованность позиций, при наличии неоднозначных слов позиции последующих слов будут совершенно другими, что приведет к большому расширению данных. Если вы используете этот метод, вам нужно найти способ быстро записывать и находить несколько позиций.
Оценка непрерывности смещения
- Идея: В настоящее время по непрерывности позиции судят о том, короткое ли это предложение, но мы начинаем с
_analyzer
Результаты можно увидеть в дополнение кposition
,У нас все еще естьstart_offset
иend_offset
, которые являются более точными, чем position. Таким образом, вы можете рассмотреть возможность использования согласованности различий смещения для оценки. - Трудности: есть два момента, на которые следует обратить внимание: во-первых, смещение, вызванное стоп-словами, является прерывистым, во-вторых, несколько пробелов в слове «new york» также вызовут несогласованность смещения. Кроме того, если вы хотите изменить эту логику, вам нужно изменить lucene, а стоимость обслуживания высока.
использованная литература
- Elasticsearch 6.6 Исходный код