Эластичный поиск - не удалось создать запрос - PullRequest
0 голосов
/ 11 февраля 2019

Я столкнулся с проблемой при доступе к данным inner_hits с помощью эластичного поиска Python.Я получаю

RequestError(400,'search_phase_execution_exception', 'failed to create query'

при попытке использовать inner_hits{}.
Моя версия с эластичным поиском 6.5.4, версия python3.7.2.

from elasticsearch import Elasticsearch
es = Elasticsearch()


mapping = '''{
        "mappings": {
    "tablets": {
      "properties": {
        "Names": {
          "type": "nested"
          "properties":{
              "ID": {"type" : "long"},
              "Combination": {"type" : "text"},
              "Synonyms": {"type" : "text"}
          }
        }
      }
    }
  }
}'''

es.indices.create(index="2", ignore=400, body=mapping)

tablets = {
    "Names":[
    {
    "ID" : 1,    
    "Combination": "Paracetamol",
    "Synonyms": "Crocin"
    },{
    "ID" : 2,
    "Combination": "Pantaprazole",
    "Synonyms": "Pantap"
    }]}

res = es.index(index="2", doc_type='json', id=1, body=tablets)

z = "patient took Pantaprazole."



res= es.search(index='2',body=
{
  "query": {
    "nested": {
      "path": "Names",
      "query": {
        "match": {"Names.Combination" : z}
      },
      "inner_hits": {} 
    }
  }
})
print(res)

Output---------------------------------------------------

    "inner_hits": {}
      File "C:\Users\aravind\AppData\Local\Programs\Python\Python37-32\lib\site-packages\elasticsearch\client\utils.py", line 76, in _wrapped
        return func(*args, params=params, **kwargs)
      File "C:\Users\aravind\AppData\Local\Programs\Python\Python37-32\lib\site-packages\elasticsearch\client\__init__.py", line 660, in search
        doc_type, '_search'), params=params, body=body)
      File "C:\Users\aravind\AppData\Local\Programs\Python\Python37-32\lib\site-packages\elasticsearch\transport.py", line 318, in perform_request
        status, headers_response, data = connection.perform_request(method, url, params, body, headers=headers, ignore=ignore, timeout=timeout)
      File "C:\Users\aravind\AppData\Local\Programs\Python\Python37-32\lib\site-packages\elasticsearch\connection\http_urllib3.py", line 186, in perform_request
        self._raise_error(response.status, raw_data)
      File "C:\Users\aravind\AppData\Local\Programs\Python\Python37-32\lib\site-packages\elasticsearch\connection\base.py", line 125, in _raise_error
        raise HTTP_EXCEPTIONS.get(status_code, TransportError)(status_code, error_message, additional_info)
    elasticsearch.exceptions.RequestError: RequestError(400, 'search_phase_execution_exception', 'failed to create query: {\n  "nested" : {\n    "query" : {\n
     "match" : {\n        "Names.Combination" : {\n          "query" : "patient took Pantaprazole.",\n          "operator" : "OR",\n          "prefix_length" : 0,\n          "max_expansions" : 50,\n          "fuzzy_transpositions" : true,\n          "lenient" : false,\n          "zero_terms_query" : "NONE",\n          "auto_generate_synonyms_phrase_query" : true,\n          "boost" : 1.0\n        }\n      }\n    },\n    "path" : "Names",\n    "ignore_unmapped" : false,\n    "score_mode" : "avg",\n    "boost" : 1.0,\n    "inner_hits" : {\n      "ignore_unmapped" : false,\n      "from" : 0,\n      "size" : 3,\n      "version" : false,\n      "explain" : false,\n      "track_scores" : false\n    }\n  }\n}')

1 Ответ

0 голосов
/ 13 февраля 2019

Спасибо за публикацию кода точно в том виде, в котором вы его выполняете, и в том смысле, что он может быть скопирован и запущен.Это очень помогает.

В JSON вашего отображения отсутствовала запятая, но ошибка была проигнорирована, поскольку вы установили ignore="400".

Вот как должен выглядеть фиксированный скрипт:

import time

from elasticsearch import Elasticsearch
es = Elasticsearch()

# fix typo - missing comma after "nested"
mapping = '''{
"mappings": {
    "tablets": {
      "properties": {
        "Names": {
          "type": "nested",
          "properties":{
              "ID": {"type" : "long"},
              "Combination": {"type" : "text"},
              "Synonyms": {"type" : "text"}
          }
        }
      }
    }
  }
}'''

# remove ignore="400"
es.indices.create(index="2", body=mapping)

tablets = {
    "Names": [
        {
            "ID": 1,
            "Combination": "Paracetamol",
            "Synonyms": "Crocin"
        }, {
            "ID": 2,
            "Combination": "Pantaprazole",
            "Synonyms": "Pantap"
        }
    ]
}

Нам также нужно установить doc_type на тот, который объявлен в отображении:

# set doc_type to 'tablets' since this is what we defined in mapping
res = es.index(index="2", doc_type='tablets', id=1, body=tablets)

z = "patient took Pantaprazole."

# allow Elasticsearch to refresh data so it is searchable
time.sleep(2)

res= es.search(index='2',body=
{
  "query": {
    "nested": {
      "path": "Names",
      "query": {
        "match": {"Names.Combination" : z}
      },
      "inner_hits": {}
    }
  }
})
print(res)

ЭтоЭто!Вывод сценария будет выглядеть следующим образом:

{'take': 7, 'timed_out': False, '_shards': {'total': 5, 'success': 5, 'skipped': 0,' не удалось ': 0},' хиты ': {' всего ': 1,' max_score ': 0.6931472,' хиты ': [{' _index ':' 2 ',' _type ':' таблетка ','_id': '1', '_score': 0.6931472, '_source': {'Names': [{'ID': 1, 'Combination': 'Paracetamol', 'Synonyms': 'Crocin'}, {'ID ': 2,' Комбинация ':' Пантапразол ',' Синонимы ':' Пантап '}]},' inner_hits ': {' Имена ': {' hit ': {' total ': 1,' max_score ': 0.6931472, 'hit': [{'_index': '2', '_type': 'tablet', '_id': '1', '_nested': {'field': 'Names', 'offset': 1}, '_score': 0.6931472, '_source': {'ID': 2, 'Combination': 'Pantaprazole', 'Synonyms': 'Pantap'}}]}}}}]}}

Почему я получил это сообщение об ошибке failed to create query?

Elasticsearch выдал ошибку failed to create query, потому что ему не удалось создать вложенный запрос против не nested поле.

Поле должно было быть nested, почему не так?

В отображении была опечатка, пропущена запятая.Elasticsearch не удалось поставить отображение.Почему не произошел сбой сценария?

Поскольку в вызове Python для es.indices.create() был установлен параметр ignore="400", из-за чего клиент Python Elasticsearch игнорировал HTTP 400код ответа , который, в свою очередь, соответствует «ошибочной форме данных».

Так почему же Elasticsearch позволил вам выполнять другие запросы, такие как индексация документов и поиск?

Потому чтоПо умолчанию Elasticsearch не потребует сопоставления и выведет его из структуры документов.Это называется динамическое отображение .

Надеюсь, это поможет!

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