使用“_bulk”端点提交 POST 请求时,来自 elasticsearch 的 400

问题描述

我已成功使用 elasticsearch 模块提交了批量 POST 请求。

但我想不使用这个模块,只使用 requests 模块。

当我尝试使用 _bulk 端点执行 POST 时遇到问题。这是代码,其中 post_object 是用于填充索引的单个文档的串联 json.dumps(...) + '\n' 字符串。注意 url 只是“http://localhost:9200/docs”。

print(f'post_object:\n{json.dumps(post_object,indent=2,default=str)}')
headers = {'Content-type': 'application/json'}        
params = {'grant_type' : 'client_credentials'}                
response = requests.post(f'{url}/_bulk',data=json.dumps(post_object,default=str) + '\n',headers=headers,params=params)        
print(f'response.json() {response.json()}')

这给出:

response.json() {'error': {'root_cause': [{'type': 'illegal_argument_exception','reason': 'Malformed action/Metadata line [1],expected START_OBJECT but found [VALUE_STRING]'}],'type': 'illegal_argument_exception',expected START_OBJECT but found [VALUE_STRING]'},'status': 400}

我之前曾尝试使 post_object 成为单个 JSON dict 的列表...但是由于另一个原因,这给出了 400:

response.json() {'error': {'root_cause': [{'type': 'illegal_argument_exception',expected START_OBJECT but found [START_ARRAY]'}],expected START_OBJECT but found [START_ARRAY]'},'status': 400}

... 有谁知道 requests 想用这个 _bulk 端点找到什么样的“START_OBJECT”?

注意有各种页面专门用于此,例如herehere。我似乎必须提交一个字符串作为 data 参数,显然带有一些元数据元素,并在正确的位置添加新行。我显然还必须将标题“Content-type”设置为“x-ndjson”,我现在已经完成了......但我只想举一个简单的例子,理想情况下!

解决方法

明白了。 ES的NB版本是7.12,Python 3.9.4。

只是想我会把这个留在这里是为了节省别人半小时的浪费时间。

是的,“内容类型”“x-ndjson”的使用被证明是必不可少的。确实需要提交一个字符串作为 post_object_str = '' for num,obj in enumerate( ... # iteration loop creating the dicts to prepare the ES documents dict_doc = {} # fill this with your fields,e.g.: dict_doc['interesting_data'] = 'something' dict_doc['timestamp'] = datetime.datetime.now() # NB you get a complaint if you try to include the "_id" field not as "metadata" post_object_str += f'{{"index": {{"_id": "{str(num)}"}}}}\n' post_object_str += json.dumps(dict_doc,default=str) + '\n' # see what it looks like print(f'post_object_str:\n{post_object_str[:400]}') headers = {'Content-type': 'application/x-ndjson'} response = requests.post(f'{url}/_bulk',data=post_object_str,headers=headers) # examine the response... print(f'post response.json():\n{json.dumps(response.json(),indent=2)}') 参数。因此:

      String word="holdup";
      char[] ch = word.toCharArray();
      HashSet<Character> result = new HashSet<Character>();
      
      for(int i=0;i<word.length();i++)
      {
        result.add(ch[i]);
      }
       System.out.println(result);


     

200:快速填充索引。漂亮。