Простой запрос термина не работает с эластичным, пока работает совпадение - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть объект JSON, как показано ниже в Elastic.

{
    "_source" : {
      "version" : 1,
      "object_id" : "f1dcae27-7a6f-4fea-b540-901c09b60a15",
      "object_name" : "testFileName_for_TestSweepAndPrune",
      "object_type" : "",
      "object_status" : "OBJ_DELETED",
      "u_attributes" : ""
    }

}

Мой запрос термина как этот не работает.

{
            "query": {
                "term": {
                    "object_status": "OBJ_DELETED"
                }
            },
            "size": 10000

}

Запрос совпадения Wile отлично работает при тех же условиях.

{
            "query": {
                "match": {
                    "object_status": "OBJ_DELETED"
                }
            },
            "size": 10000

}

Хотите знать, что здесь может происходить?Как я могу заставить термин запроса работать здесь для этого условия?

1 Ответ

0 голосов
/ 20 сентября 2018

Чтобы понять, почему запрос term не работает так, как вы ожидаете, нам нужно проверить, как ElasticSearch обрабатывает и сохраняет данные и чем отличаются запросы match и term.

Обычно, когдаВы сохраняете некоторый текст в ElasticSearch, сначала он анализируется, а затем сохраняется.Анализ выполняется анализатором .Существует много анализаторов, но если вы не укажете их, будет использоваться стандартный.Анализатор обрабатывает текст, преобразует его в массив токенов и сохраняет список токенов.Правила разделения текста на токены различны для каждого конкретного анализатора.

Когда текст обработан и сохранен, вы можете запросить его.Существует много способов запроса чего-либо, но в вашем случае основное различие между match и term заключается в том, что match - это полнотекстовый запрос , а term - это запрос уровня термина .Дело в том, что в случае полнотекстового поиска ваша строка запроса анализируется так же, как и поле, которое вы запрашиваете.В запросах уровня термина строка запроса не анализируется.Важно отметить.

Теперь давайте посмотрим, как "OBJ_DELETED" анализируется с помощью ElasticSearch.Для этого мы можем добавить простой документ, подобный этому:

curl -X PUT 'localhost:9200/testdata/object/1' -H 'Content-Type: application/json' -d '{ "object_status": "OBJ_DELETED"  }'

Затем убедитесь, что все есть:

curl -X POST 'localhost:9200/testdata/_search?pretty'

должно выдать что-то вроде этого:

...
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
  {
    "_index" : "testdata",
    "_type" : "object",
    "_id" : "1",
    "_score" : 1.0,
    "_source" : {
      "object_status" : "OBJ_DELETED"
    }
  }
]

}

Теперь мы можем проверить, как анализируется "OBJ_DELETED":

curl -X POST 'localhost:9200/testdata/_analyze?pretty' -H 'Content-Type: application/json' -d '{ "text": "OBJ_DELETED"  }'

и он выводит:

{
  "tokens" : [
    {
      "token" : "obj_deleted",
      "start_offset" : 0,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 0
    }
  ]
}

Как вы можете видеть, он конвертирует только текст в нижний регистри сохранил его как один токен.Вот как это делает анализатор по умолчанию.Теперь вернемся к вашим запросам.match запрос работает, потому что значение запроса "OBJ_DELETED" также преобразуется в нижний регистр под капотом и, таким образом, ElasticSearch может его найти.И для term запроса строка запроса не обрабатывается, так что на самом деле вы сравниваете OBJ_DELETED с obj_deleted и, очевидно, вы не получаете результатов.

И последний вопрос: почему object_status.keyword работает для termquery?

По умолчанию ElasticSearch создать дополнительное отображение для каждого текстового поля.Это своего рода метаданные, которые вы можете использовать.Также это позволяет обрабатывать одно и то же значение по-разному.Таким образом, по умолчанию каждое поле text имеет дополнительное сопоставление с именем keyword, которое имеет тип ключевое слово .keyword поля не анализируются (их можно нормализовать только при необходимости).Это означает, что для отображения по умолчанию сохраняется точное значение, которое вы передаете ElasticSearch (OBJ_DELETED в вашем случае).

...