【发布时间】:2020-01-16 09:04:42
【问题描述】:
我发现这种问题很难命名,但它一定很简单,而且我缺少一些基本的东西。
假设我有以下 Python dict() :
import json
dct = dict()
dct['hits'] = dict()
dct['hits']['hits'] = dict()
dct['hits']['hits']['a'] = 'b'
dct['hits']['hits']['b'] = 'c'
dct['aggregations'] = dict()
dct['aggregations']['a'] = 1
dct['aggregations']['b'] = 2
print(json.dumps(dct, indent=2))
{
"hits": {
"hits": {
"a": "b",
"b": "c"
}
},
"aggregations": {
"a": 1,
"b": 2
}
}
这可能看起来很熟悉,因为它是 ElasticSearch 返回结果的结构。
我正在构建一个使用该结果的函数。但有时我想访问dct['hits']['hits'] 有时我想访问dct['aggregations']。
当然,我会使用一个带有变量的函数来建议我想访问哪个字段,如下所示:
def foo(field):
return dct[field]
如果field='aggregations' 这一切都很好。但是当我希望该字段为 ['hits']['hits'] 时该怎么办?
解决它的一种方法(但它很丑),迭代方法:
def foo(fields=('hits','hits')):
wanted = dct
for field in fields:
wanted = wanted[field]
return wanted
a = foo()
a
Out[47]: {'a': 'b', 'b': 'c'}
a = foo(('aggregations',))
a
Out[51]: {'a': 1, 'b': 2}
我正在尝试修改的实际功能:
def execute_scroll_query(es_client, query, indexes):
try:
response = es_client.search(index=indexes, scroll='2m', size=1000, body=query)
scroll_size = len(response['hits']['hits'])
sid = response['_scroll_id']
while scroll_size > 0:
try:
for hit in response['hits']['hits']:
yield hit
response = es_client.scroll(scroll_id=sid, scroll='2m')
sid = response['_scroll_id']
scroll_size = len(response['hits']['hits'])
except Exception:
print("Unexpected Exception while scrolling")
except Exception:
print("Unexpected Exception while fetching")
【问题讨论】:
-
尝试使用递归函数。(如果返回的元素是字典,则再次调用该函数,直到你有一个非字典对象)
-
迭代方法可能会以一种丑陋的方式解决它。我想要更简单和 Pythoic 的东西。我将编写该解决方案作为示例
-
然后尝试使用eval函数link
-
dct[field]vsfoo(field)- 看起来你并没有真正通过拥有这个功能获得太多 -
或者可能是星号运算符,因此您可以将任意数量的参数传递给函数。
标签: python json elasticsearch