我发现这个问题很难找到,但它必须是一个简单的问题,而我却缺少一些基本的东西。

假设我有以下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返回结果的结构。

我正在构建一个使用该结果的function。但有时我想访问dct['hits']['hits']有时我想访问dct['aggregations']

当然,我会使用带有变量的function来建议我想要访问哪个字段,如下所示:

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}

我正在尝试修改的实际function:

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")
分析解答

您可以传递list键并迭代获取该项:

def foo(fields):
    for field in fields:
        dct = dct[field]
    return dct

foo(['hits', 'hits'])
# The value of dct['hits']['hits']