Auf dem Weg zur perfekten ES-Abfragegenerierung mit Elastic-builder

Veröffentlicht Apr 9, 2020


Bei allem Respekt vor dem, was ES(ElasticSearch) im Vergleich zu den anderen Speicher-Engines für die Abfrage von Daten bietet, ist einer seiner Nachteile die potenzielle Komplexität der Abfragen. Allgemein gesagt, wenn Sie ein Post-Objekt an einen ES-Endpunkt senden möchten, könnte die Konstruktion dieses Objekts komplizierter als gewöhnlich werden, insbesondere wenn das Ziel darin besteht, Daten durch Filterung abzurufen. Vor einigen Jahren gab es nicht viel Dokumentation darüber, wie man komplexe ES-Abfragen erstellt, und es gab auch nicht viele Werkzeuge wie Bibliotheken und Pakete für die Erstellung von ES-Abfragen. Dies änderte sich jedoch mit dem Aufkommen der elastic.js Lib für Javascript und insbesondere mit ihrem node.js Nachfolger - dem elastic-builder Paket.

Wie hat unsere Geschichte mit der ES-Abfragegenerierung begonnen?

Im Laufe von zwei Jahren haben wir an einem bestimmten Produkt gearbeitet, bei dem wir ES-Abfragen verwendet haben. Mit der Zeit wurde uns die Notwendigkeit bewusst, die Generierung solcher Abfragen zu optimieren. Jedes Mal, wenn wir etwas ändern mussten, war dies für uns mit einem hohen Aufwand verbunden. Also beschlossen wir, eine Lösung zu finden, um die Generierung von ES-Abfragen zu vereinfachen.

Nach vielen Überlegungen und Diskussionen haben wir schließlich das elastic-builder-Paket verwendet, um den Code für die Generierung von ES-Abfragen in unserem Angular-Projekt zu optimieren.

In diesem Beitrag werden wir nicht darüber sprechen, ob das Schreiben von benutzerdefiniertem Code eine bessere Lösung ist als die Verwendung eines Drittanbieter-Pakets oder ob Angular das am besten geeignete FE-Framework ist. Stattdessen werden wir uns nur auf einige Schlüsselsegmente unserer Lösung in Bezug auf die ES-Abfragen konzentrieren und sie in zwei Teilen erklären - Teil 1, der den ererbten Status zusammen mit den Hauptproblemen beschreibt, und Teil 2, der die verbesserte Lösung mit dem elastic-builder enthält.

Die Geburt unserer Abfrage

In der ersten Phase war die Anforderung eine einfache Filterung der Aufgaben nach verschiedenen Parametern wie Land, Status, etc. Zu diesem Zeitpunkt gingen wir davon aus, dass sich die Form der Abfrage nicht ändern würde, also schrieben wir mehrere Zeilen, um das Post-Objekt, das für die Bereitstellung der benötigten Ausgabe erforderlich ist, manuell einzustellen. Der unten gezeigte JSON-Baum war mehr oder weniger einfach:

Towards_Perfect_ES_Query_Generation_with_Elastic_builder_2.webp

Um nur den Must-Teilbaum zu erzeugen, mussten wir mehrere Arrays, Objekte und Bedingungen verwenden, wobei zu berücksichtigen war, dass einige der Filter möglicherweise gar nicht existieren*(Vorhersage*) oder mehrere Werte haben können*(Status*):

let must: Array<any> = [ { "match": { "country": { "query": country, "type": "phrase" } } } ]; if (!!statusList.length) { let query = statusList.map(status => "(" + status + ")").join(' OR '); must.push({ "query_string": { "default_field": "status", "query": query }        
    }); } if (prediction) { must.push({ "match": { "prediction": { "query": prediction, "type": "phrase" } } }); } let boolObject = {"must": must}; let postObject = { "query": { "bool": boolObject } };

Die Ausgabe dieser Generierung entspricht dem, was wir wollten, da wir die Struktur der Abfrage im Voraus kennen mussten:

"query": { "bool": { "must": [ { "match": { "country": { "query": country, "type": "phrase" } } }, { "query_string": { "default_field": "status", "query": "(" + status_1 + ") OR (" + status_2 + ")" } }, { "match": { "prediction": { "query": Vorhersage, "type": "phrase" } } } ] } }

Wir haben einen ähnlichen Ansatz für die Teilbäume "Filter" und " Sort" verwendet, da wir der Meinung waren, dass der benutzerdefinierte Code für die Generierung der gesamten Abfrage wahrscheinlich groß genug war, um zu diesem Zeitpunkt eine Alternative in Betracht zu ziehen. Vorerst blieben wir beim Status quo und ahnten nicht, dass mehr und mehr Anforderungen früher als erwartet kommen würden.

Die Agonie der Erweiterung einer Abfrage

Im Laufe der Zeit wurde gefordert, dass die Abfragen benutzerdefinierte Suche, erweiterte Filterung, bedingte Filterung und so weiter bieten sollten. Darüber hinaus nahm die Anzahl der Filterwerte und Bedingungen drastisch zu. Jedes Mal, wenn wir versuchten, die Abfrage zu erweitern, war mehr und mehr benutzerdefinierter Code involviert, und wir waren uns nicht bewusst, dass dies den Generierungsprozess langsam verschmutzen würde. Dies führte zu mehr Fehlern als ursprünglich erwartet, und es wurde für die Entwickler, die erst kürzlich zu dem Projekt gestoßen waren, fast unmöglich, den Code zu verstehen.

Towards_Perfect_ES_Query_Generation_with_Elastic_builder_3.webp

Bei solch komplexen Abfragen macht es keinen Sinn, zu zeigen, wie der JSON-Baum aussehen wird. Er wird einem Wald ähneln, da die verschiedenen Bedingungen für die Generationen in erster Linie auf den Statuswerten basieren, was immer zu einem separaten Baum pro Bedingung führt.

Das Gleiche gilt für den Code in der Generierungsmethode. Es ist unvorstellbar, einen solchen Code zu präsentieren, und deshalb werden wir uns im zweiten Teil des Blogbeitrags nur auf die kleineren Teile konzentrieren, die tatsächlich die wichtigsten Punkte darstellen, damit Sie in Betracht ziehen, dem elastic-builder eine Chance zu geben.

Velimir Graorkoski

Velimir Graorkoski

Software Engineer - AI

Buchen Sie eine kostenlose Beratung

Wählen Sie Ihre Branche*

Bitte wählen Sie Ihre Branche*

Wählen Sie Ihren Servicetyp

Bitte wählen Sie Ihren Servicetyp

calendarWann passt es Ihnen am besten für ein kurzes Gespräch

Die mit * gekennzeichneten Felder sind Pflichtfelder

Diese Website ist durch reCAPTCHA geschützt und es gelten die Datenschutzerklärung und Nutzungsbedingungen von Google.

Zeit- und Materialaufwand vs. Festpreis

Zeit und Materialien vs. Festpreis: Welches Vertragsmodell reduziert das finanzielle Risiko?

Mar 31, 2026
Wenn die meisten Leute über Zeit und Materialien oder Festpreise diskutieren, sehen sie dies als eine Frage des Projektmanagements. Welches Modell passt zu unserem Arbeitsablauf? Welches Modell passt zu unserem Entwicklungsteam? Diese Fragen sind wichtig - aber sie gehen am Kern der Sache vorbei. Für einen CFO oder Finanzleiter lautet die eigentliche Frage: Wo liegt das finanzielle Risiko? Die Ve
Aneta Pejchinoska

Aneta Pejchinoska

Scope Creep in der Softwareentwicklung

Verhinderung von Scope Creep in der Softwareentwicklung: Wie man Software-Budgets vorhersehbar hält

Mar 30, 2026
Seien wir ehrlich - Software-Projekte haben den Ruf, das Budget zu sprengen. Und in den meisten Fällen ist die schleichende Ausweitung des Projektumfangs der Übeltäter, der sich im Verborgenen hält. Nach Angaben des Project Management Institute (PMI) verschwenden Unternehmen im Durchschnitt 97 Millionen Dollar pro 1 Milliarde Dollar, die in Projekte investiert werden, aufg
Aneta Pejchinoska

Aneta Pejchinoska

Ein einfacher Leitfaden zur WCAG-2.1-Konformität

Ein einfacher Leitfaden zur WCAG-2.1-Konfortmität

Jan 4, 2026
Barrierefreiheit sollte von Anfang an in Ihr Produkt integriert sein, nicht erst später hinzugefügt werden. Wenn Menschen mit Behinderungen Ihre Benutzeroberfläche nicht nutzen können, verlieren Sie Kunden, erhöhen die Supportkosten und gehen rechtliche Risiken ein. Die Zugänglichkeitsrichtlinien für Webinhalte (WCAG 2.1) stammen vom World Wide Web Consortium. Betrachten Sie sie als das Regelwerk
Intertec

Intertec

Alle Beiträge anzeigen