【问题标题】:Elasticsearch with Python Requests: msearch request must be terminated by a newline使用 Python 请求的 Elasticsearch:msearch 请求必须由换行符终止
【发布时间】:2020-08-08 20:06:45
【问题描述】:

我正在使用带有 Python 请求的 msearch 并收到以下错误:

msearch 请求必须以换行符终止 [\n]

我查看了许多其他相关的问题/答案,但它们要么使用 cURL、带有查询的文本文件,要么使用 Python es API。我需要使用请求,并且我的查询生成为列表/字典。

url  = <host>+"/" +  'books/_msearch' # books is the index
region = <region>
service = 'es'
credentials = boto3.Session().get_credentials()
awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)

payload = [{}, 
           {"query": {"bool": {"filter": [{"terms": {"user_id": [504401]}}]}}, "size": 0},
          {}, 
          {"query": {"bool": {"filter": [{"terms": {"user_id": [504401]}}]}}, "size": 0}
]
                   
r = requests.post(url, auth=awsauth, json=payload)

query_results = json.loads(r.text)

我也试过了:

payload = json.dumps(payload) + "\n"

同样的错误。

我也试过了:

    r = ""
    for d in payload:
        r += json.dumps(d) + "\n"

    r = requests.post(url, auth=awsauth, json=r)

同样的错误。

【问题讨论】:

  • 你可以试试data arg而不是json吗?
  • 这给了我另一个错误:缺少 Content-Type 标头
  • 将参数headers 设置为headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}。另外,您可以将 POST 正文更改为单个字典而不是列表吗?
  • 做到了!我需要添加一个标头,将 json 更改为数据,还需要添加“for d in search_arr:”位以添加 \n
  • 不错!祝你好运!

标签: python elasticsearch


【解决方案1】:

感谢@wholevinski 的回答(在问题 cmets 中)。我需要将 json 更改为数据并添加标题。另外,我需要做 \n 循环。

payload = [{}, 
           {"query": {"bool": {"filter": [{"terms": {"user_id": [504401]}}]}}, "size": 0},
          {}, 
          {"query": {"bool": {"filter": [{"terms": {"user_id": [504401]}}]}}, "size": 0}
] # same as in question

data_as_str = ""
for d in payload:
    data_as_str += json.dumps(d) + "\n"                 
    
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
# "Accept: text/plain" may not be necessary

r = requests.post(url, headers=headers, auth=awsauth, data=data_as_str)

query_results = json.loads(r.text)

【讨论】:

    【解决方案2】:

    这是一个想法:

    r = requests.post(url,
                      data="\n".join(
                          [json.dumps(elem) for elem in payload]
                      )+"\n",
                      headers={'Content-Type': 'application/x-ndjson'})
    

    Accept: text/plain 是一个unnecessary workaround

    【讨论】:

    • 谢谢。这也应该有效,我写出了@wholevinski 提供的答案,因为我就是这么做的。
    • 酷。仅仅因为它有效并不意味着它是正确的?
    猜你喜欢
    • 2019-08-25
    • 2020-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多