Python对接Elasticsearch API报错:ObjectApiResponse不支持元素赋值
问题解决:TypeError: 'ObjectApiResponse' object does not support item assignment
错误原因
Elasticsearch Python客户端返回的ObjectApiResponse是不可变的响应对象,无法像普通字典那样直接执行键值对赋值操作,因此res['ST'] = search_term会触发类型错误。
修复方案
1. 将响应对象转为可修改字典
把es.search()返回的结果转换成普通Python字典,之后再进行赋值和修改操作。
2. 修正循环内的return位置
原代码中return render_template写在for循环内部,会导致仅处理第一个搜索结果就返回页面,需将return语句移到循环外部,确保所有结果都被处理。
修改后的完整代码
from flask import Flask, render_template, request from elasticsearch import Elasticsearch import os os.chdir('/home/ambu/Documents/search') app: Flask = Flask(__name__, template_folder='templates') es = Elasticsearch("http://127.0.0.1:9200") @app.route('/') def index(): return render_template('search.html') @app.route('/search/results', methods=['GET', 'POST']) def request_search(): search_term = request.form["input"] res = es.search( index='data_example4', body={ "query": {"match": {"content": search_term}}, "highlight": {"pre_tags": ["<b>"], "post_tags": ["</b>"], "fields": {"content": {}}}} ) # 将不可变响应转为可修改字典 res_dict = dict(res) res_dict['ST'] = search_term for hit in res_dict['hits']['hits']: # 增加判断避免索引越界 highlight_content = hit.get('highlight', {}).get('content', []) if len(highlight_content) > 1: hit['good_summary'] = '….'.join(highlight_content[1:]) else: hit['good_summary'] = highlight_content[0] if highlight_content else hit['_source']['content'] # 移至循环外,确保所有结果处理完成后返回 return render_template('results.html', res=res_dict) if __name__ == '__main__': app.run('127.0.0.1', debug=True)
额外说明
- 也可以使用
res.to_dict()完成转换,这是Elasticsearch响应对象提供的官方方法,和dict(res)效果一致。 - 新增的索引越界判断,可避免当高亮内容仅有一段时触发
IndexError。
内容的提问来源于stack exchange,提问作者Felipe Araque
相关产品推荐
相关产品推荐

