Distinct-Feldwerte in ElasticSearch abfragen
English
Deutsch
Nehmen wir an, wir haben einen ElasticSearch-Index namens strings mit einem Feld pattern vom Typ {"type": "keyword"}.
Die Top N Werte der Spalte abrufen
Wenn wir die Top N (12 in unserem Beispiel) Einträge abrufen möchten, d.h. die patterns, die in den meisten Dokumenten vorhanden sind, können wir diese Abfrage verwenden:
terms_aggregation_query.json
{
"aggs" : {
"patterns" : {
"terms" : {
"field" : "pattern.keyword",
"size": 12
}
}
}
}Vollständiges Beispiel in Python:
es_terms_example.py
from elasticsearch import Elasticsearch
es = Elasticsearch()
result = es.search(index="strings", body={
"aggs" : {
"patterns" : {
"terms" : {
"field" : "pattern.keyword",
"size": 12
}
}
}
})
for aggregation in result["aggregations"]["patterns"]["buckets"]:
print(aggregation) # e.g. {'key': 'mypattern, 'doc_count': 2802}Siehe die Terms-Aggregation-Dokumentation für weitere Informationen.
Alle distinct-Werte der Spalte abrufen
Alle Werte abzurufen ist etwas komplizierter, da wir eine Composite-Aggregation verwenden müssen, die einen after_key zurückgibt, um die Abfrage zu paginieren.
Diese Python-Hilfsfunktion paginiert die Abfrage automatisch mit konfigurierbarer Seitengröße:
es_iterate_distinct.py
from elasticsearch import Elasticsearch
es = Elasticsearch()
def iterate_distinct_field(es, fieldname, pagesize=250, **kwargs):
"""
Hilfsfunktion um alle distinct-Werte aus ElasticSearch abzurufen
(sortiert nach Anzahl der Vorkommen)
"""
compositeQuery = {
"size": pagesize,
"sources": [{
fieldname: {
"terms": {
"field": fieldname
}
}
}
]
}
# Über Seiten iterieren
while True:
result = es.search(**kwargs, body={
"aggs": {
"values": {
"composite": compositeQuery
}
}
})
# Jeden Bucket ausgeben
for aggregation in result["aggregations"]["values"]["buckets"]:
yield aggregation
# "after"-Feld setzen
if "after_key" in result["aggregations"]["values"]:
compositeQuery["after"] = \
result["aggregations"]["values"]["after_key"]
else: # Fertig!
break
# Verwendungsbeispiel
for result in iterate_distinct_field(es, fieldname="pattern.keyword", index="strings"):
print(result) # e.g. {'key': {'pattern': 'mypattern'}, 'doc_count': 315}Check out similar posts by category:
Databases, ElasticSearch, Python
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow