我正在尝试为ElasticSearch动态构建查询,这是我的代码:
import json
query_string = "person human"
query = {}
query['query'] = {}
query['query']['bool'] = {}
query['query']['bool']['must'] = {}
must_string = []
term_string = {}
term_string['term'] = {}
term_string['term']["labels.Name"] = ""
for term in query_string.split():
term_string['term']["labels.Name"] = term
must_string.append(term_string)
query['query']['bool']['must'] = must_string
print(json.dumps(query))
我期待这样的输出:
{"query": {"bool": {"must": [{"term": {"labels.Name": "person"}}, {"term": {"labels.Name": "human"}}]}}}
但是我得到了这个:
{"query": {"bool": {"must": [{"term": {"labels.Name": "human"}}, {"term": {"labels.Name": "human"}}]}}}
注意,该值在labels.Name
中是重复的。
当我在列表中追加内容时,会覆盖先前的值。
答案 0 :(得分:1)
您每次将同一本词典添加到列表中。引用仅针对一本词典。您可以通过每次构造新字典来引用新字典:
for term in query_string.split():
term_string = {}
term_string['term'] = {}
term_string['term']["labels.Name"] = ""
term_string['term']["labels.Name"] = term
must_string.append(term_string)
对于构建嵌套字典,我建议您使用collections.defaultdict
:请参见defaultdict of defaultdict, nested。
答案 1 :(得分:1)
问题不是列表,而是字典:您更新了
的值term_string['term']["labels.Name"]
在每次for循环中。您可以替换
term_string['term']["labels.Name"] = term
通过类似的方式
term_string = {'term':{'labels.name':term}}
答案 2 :(得分:0)
Python字典通过引用传递。这意味着当您追加到must_string
时,您实际上是在追加对term_string
字典的引用,以便在以下循环中修改term_string字典时,它会更改基础字典,而不仅仅是最后一个版本
要执行所需的操作,您需要为要添加的每个循环创建一个新字典,或者可以在开始之前对字典进行deepcopy()
(来自copy
库)附加它。