in eland/query_compiler.py [0:0]
def _flatten_dict(self, y, field_mapping_cache: "FieldMappingCache"):
out = {}
def flatten(x, name=""):
# We flatten into source fields e.g. if type=geo_point
# location: {lat=52.38, lon=4.90}
if name == "":
is_source_field = False
pd_dtype = "object"
else:
try:
pd_dtype = field_mapping_cache.field_name_pd_dtype(name[:-1])
is_source_field = True
except KeyError:
is_source_field = False
pd_dtype = "object"
if not is_source_field and isinstance(x, dict):
for a in x:
flatten(x[a], name + a + ".")
elif not is_source_field and isinstance(x, list):
for a in x:
flatten(a, name)
elif is_source_field: # only print source fields from mappings
# (TODO - not so efficient for large number of fields and filtered mapping)
field_name = name[:-1]
# Coerce types - for now just datetime
if pd_dtype == "datetime64[ns]":
x = elasticsearch_date_to_pandas_date(
x, field_mapping_cache.date_field_format(field_name)
)
# Elasticsearch can have multiple values for a field. These are represented as lists, so
# create lists for this pivot (see notes above)
if field_name in out:
if not isinstance(out[field_name], list):
field_as_list = [out[field_name]]
out[field_name] = field_as_list
out[field_name].append(x)
else:
out[field_name] = x
else:
# Script fields end up here
# Elasticsearch returns 'Infinity' as a string for np.inf values.
# Map this to a numeric value to avoid this whole Series being classed as an object
# TODO - create a lookup for script fields and dtypes to only map 'Infinity'
# if the field is numeric. This implementation will currently map
# any script field with "Infinity" as a string to np.inf
if x == "Infinity":
out[name[:-1]] = np.inf
else:
out[name[:-1]] = x
flatten(y)
return out