Как отправить список вложенных запросов булевых фильтров в Elasticsearch с помощью pycurl?

Я использую ElasticSearch 1.5. У меня настроено восемь узлов и отдельный клиентский узел. Я посылаю запрос фильтра в движок через Python, используя pycurl. Я пытаюсь создать несколько вложенных логических фильтров. Я могу заставить работать два отдельных одиночных логических фильтра, но когда я пытаюсь связать их вместе, я получаю следующую ошибку:

{u'error': u'SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[hT6TiTqoTpGaCr45SrjUtg][ships][0]: RemoteTransportException[[Kaitlyn][inet[/172.31.14.203:9300]][indices:data/read/search[phase/query]]]; nested: SearchParseException[[ships][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{"qu1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ufffd\ufffd\ufffd3\ufffd\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"must": 1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ufffd\ufffd\ufffd3\ufffd\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"melia"}1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ufffd\ufffd\ufffd3\ufffd\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00": {"sho1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ufffd\ufffd\ufffd3\ufffd\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}}, {"te1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ufffd\ufffd\ufffd3\ufffd\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 {"match1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]]]; nested: JsonParseException[Illegal unquoted character ((CTRL-CHAR, code 0)): has to be escaped using backslash to be included in name\n at [Source: UNKNOWN; line: 1, column: 7]]; }

Может кто-нибудь сказать мне, что я делаю не так?

ФОН

Следующий код работает для данных, определенных как

data = {
  "query": {
    "filtered": {
      "query": {"match_all":{}},
      "filter": {
        "bool": {
          "must": [
            {"bool": {
                "should": [
                  { "term": {"stuff":"thingamabobs"}},
                  { "term": {"stuff":"trucs"}}
                ]
              }
            }
          ]
        }
      }
    }
  }
}

и когда данные определены как

data = {
  "query": {
    "filtered": {
      "query": {"match_all":{}},
      "filter": {
        "bool": {
          "must": [
            {"bool": {
                "should": [
                  { "term": {"name":"melia"}},
                  { "term": {"name":"heli"}}
                ]
              }
            },
          ]
        }
      }
    }
  }
}

но не когда данные определены как (два фильтра объединены, по-видимому, неправильно)

data = {
  "query": {
    "filtered": {
      "query": {"match_all":{}},
      "filter": {
        "bool": {
          "must": [
            {"bool": {
                "should": [
                  { "term": {"name":"melia"}},
                  { "term": {"name":"heli"}}
                ]
              }
            },
            {"bool": {
                "should": [
                  { "term": {"stuff":"thingamabobs"}},
                  { "term": {"stuff":"trucs"}}
                ]
              }
            }
          ]
        }
      }
    }
  }
}

Вот фрагмент кода.

import pycurl
import json
from StringIO import StringIO
from pprint import pprint
import time

def handlePycurlResult(result):
  resultDict = json.loads(result)
  print 'handlePycurlResult', type(resultDict)
  pprint(resultDict)

data = ...

c = pycurl.Curl()
c.setopt(c.WRITEFUNCTION, handlePycurlResult)
c.setopt(c.URL, 'http://localhost:9200/owners/owner/_search?pretty')
c.setopt(pycurl.HTTPHEADER, ['Accept: application/json'])
c.setopt(c.POST, 1)
c.setopt(c.POSTFIELDS, json.dumps(data))
c.perform()
c.close()

За исключением документов JSON, которые я создаю с использованием объектов Python, приведенный выше код эффективно копирует пример преобразования языка curl в pycurl.

1 ответ

Я не вижу ничего плохого в вашем запросе. Тем не менее, ошибка, которую вы получаете, жалуется на пустые символы (т.е. \x00) присутствовать в вашем запросе JSON, и это проблема:

Failed to parse source [{"qu1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ufffd\ufffd\ufffd3\ufffd\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"must"
...
JsonParseException[Illegal unquoted character ((CTRL-CHAR, code 0)): has to be escaped using backslash to be included in name 

Если вы редактируете свой запрос в другом месте, а затем копируете / вставляете его в код Python, попробуйте сначала проверить его (например, по адресу http://jsonformatter.curiousconcept.com/) и вставить полученный компактный JSON (то есть без пробелов) в ваш код, чтобы увидеть, что происходит.

Другие вопросы по тегам