def _flatten_dict()

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