Подтвердить что ты не робот

ElasticSearch не возвращает результаты запроса терминов по отношению к строковому свойству

У меня есть следующий индексный документ:

{
    "visitor": {
        "id": <SOME STRING VALUE>
    }
}

Отображение для документа:

"visitor": {
    "properties": {
        "id": {
            "type": "string"
         }
     }
 }

Когда я запускаю следующий запрос, я получаю результаты:

{
    "query": {
        "filtered": {
            "query": {
                "match_all": {}
             }
        },
        "filter": {
            "term": { "visitor.id": "123" }
        }
    }
}

Однако это не так:

{
    "query": {
        "filtered": {
            "query": {
                "match_all": {}
             }
        },
        "filter": {
            "term": { "visitor.id": "ABC" }
        }
    }
}

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

Может ли кто-нибудь сказать мне, почему я не могу фильтровать посетителя с идентификатором "ABC", но может для посетителей 123

4b9b3361

Ответ 1

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

Анализ выполняется в два очень специфических раза - во время индексации (когда вы помещаете материал в elasticsearch) и, в зависимости от вашего запроса, во время поиска (в строке, которую вы ищете).

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

Чтобы привести это в пример, когда вы сохраняете строку "Я люблю пирог Винсента!" в elasticsearch, и вы используете стандартный анализатор по умолчанию, вы на самом деле сохраняете "i", "love", "vincent", "s", "pie". Затем, когда вы пытаетесь найти "Vincent's" с запросом term (который не анализируется), вы ничего не найдете, потому что "Винсент" не является одним из этих жетонов! Однако, если вы ищете "Vincent's", используя запрос match (который проанализирован), вы найдете "Я люблю пирог Винсента!". потому что "vincent" и "s" находят совпадения.

В нижней строке:

  • Используйте анализируемый запрос, например match, при поиске строк естественного языка.
  • Настройте анализаторы в соответствии с вашими потребностями. Вы можете настроить настраиваемый анализатор, который выполняет токенизатор пробела или буквенный токенизатор или токенатор шаблона, если вы хотите усложниться, а также любые фильтры, которые вам нужны. Это зависит от вашего варианта использования, но если вы имеете дело с предложениями на естественном языке, я не рекомендую это, потому что стандартный токенизатор был создан для поиска естественного языка.
  • Вы можете настроить поле, чтобы не использовать анализатор со следующим отображением, которое должно соответствовать вашим потребностям:

    "visitor": {
        "properties": {
            "id": {
                "type": "string"
                "index": "not_analyzed"
            }
        }
    }
    

Подробнее см. http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/analysis.html.

Ответ 2

Если вы не укажете поле visitor.id, которое НЕ анализируется, по умолчанию все поля анализируются.

Это означает, что "ABC" будет индексироваться как "abc" (нижний регистр).

Вы должны использовать термин query или term filter со строкой в ​​ LOWER CASE.

Я надеюсь, что следующий запрос будет работать. ^^

{
    "query": {
        "filtered": {
            "query": {
                "match_all": {}
             }
        },
        "filter": {
            "term": { "visitor.id": "abc" }
        }
    }
}