Skip to content

Commit 125a1b4

Browse files
authored
Get all nested fields in Elasticsearch (#1882)
* Get all nested fields in Elasticsearch When using the Elasticsearch provider for a collection, the only queryables returned are the first-level properties of its features. With this change, all nested properties are returned as fields and it's possible to filter items using those nested properties (e.g. /items?prop1.prop2=example ) * Remove whitespace from blank lines * Fix indentation
1 parent 88bfa5f commit 125a1b4

1 file changed

Lines changed: 28 additions & 12 deletions

File tree

pygeoapi/provider/elasticsearch_.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,36 @@ def get_fields(self):
119119
LOGGER.warning('could not get fields; returning empty set')
120120
return {}
121121

122-
for k, v in p['properties'].items():
123-
if 'type' in v:
124-
if v['type'] == 'text':
125-
self._fields[k] = {'type': 'string'}
126-
elif v['type'] == 'date':
127-
self._fields[k] = {'type': 'string', 'format': 'date'}
128-
elif v['type'] in ('float', 'long'):
129-
self._fields[k] = {'type': 'number',
130-
'format': v['type']}
131-
else:
132-
self._fields[k] = {'type': v['type']}
133-
122+
self._fields = self.get_nested_fields(p, self._fields)
134123
return self._fields
135124

125+
def get_nested_fields(self, properties, fields, prev_field=None):
126+
"""
127+
Get Elasticsearch fields (names, types) for all nested properties
128+
129+
:param properties: `dict` of Elasticsearch mappings properties
130+
:param fields: `dict` of fields in the current iteration
131+
:param prev_field: name of the parent field
132+
133+
:returns: dict of fields
134+
"""
135+
for k, v in properties['properties'].items():
136+
137+
cur_field = k if prev_field is None else f'{prev_field}.{k}'
138+
139+
if isinstance(v, dict) and 'properties' in v:
140+
fields = self.get_nested_fields(v, fields, cur_field)
141+
else:
142+
if v['type'] == 'text':
143+
fields[cur_field] = {'type': 'string'}
144+
elif v['type'] == 'date':
145+
fields[cur_field] = {'type': 'string', 'format': 'date'}
146+
elif v['type'] in ('float', 'long'):
147+
fields[cur_field] = {'type': 'number', 'format': v['type']}
148+
else:
149+
fields[cur_field] = {'type': v['type']}
150+
return fields
151+
136152
@crs_transform
137153
def query(self, offset=0, limit=10, resulttype='results',
138154
bbox=[], datetime_=None, properties=[], sortby=[],

0 commit comments

Comments
 (0)