Unsere REST-API ermöglicht es Benutzern, benutzerdefinierten schemaligen JSON zu einigen unserer REST-Ressourcen hinzuzufügen, und wir müssen sie in Elasticsearch durchsuchen können. Diese benutzerdefinierten Daten und ihre Struktur können in Ressourcen desselben Typs völlig unterschiedlich sein.Schematische Unterstützung für elastische Suchabfragen
Betrachten Sie dieses Beispiel Dokument:
{
"givenName": "Joe",
"username": "joe",
"email": "[email protected]",
"customData": {
"favoriteColor": "red",
"someObject": {
"someKey": "someValue"
}
}
}
Alle Felder außer customData
ein Schema einzuhalten. customData
ist immer ein JSON-Objekt, aber alle Felder und Werte in diesem Objekt können von Ressource zu Ressource stark variieren. Es gibt keine Garantie dafür, dass ein bestimmter Feldname oder -wert (oder sogar ein Werttyp) innerhalb von customData für zwei Ressourcen identisch ist, da Benutzer diese Felder beliebig bearbeiten können.
Was ist der beste Weg, um die Suche nach diesem zu unterstützen?
Wir dachten, eine Lösung wäre, nur kein Mapping für customData
zu erstellen, wenn der Index erstellt wird, aber dann wird es unqueryable (was im Gegensatz zu dem ES docs say ist). Dies wäre die ideale Lösung, wenn Abfragen für nicht zugeordnete Eigenschaften ausgeführt werden und bei diesem Ansatz keine Leistungsprobleme auftreten. Nachdem wir mehrere Tests durchgeführt hatten, konnten wir dies jedoch nicht zum Laufen bringen.
Ist das etwas, das spezielle Konfiguration benötigt? Oder sind die Dokumente falsch? Etwas Klärung, warum es nicht funktioniert, würde sehr geschätzt werden.
Da dies derzeit nicht für uns arbeiten, haben wir von ein paar alternativen Lösungen gedacht:
Reindizieren: dies kostspielig sein würde, wie wir jeden Index indizieren müssten, die dieses Dokument enthält und tun also jedes Mal, wenn ein Benutzer eine Eigenschaft mit einem anderen Werttyp aktualisiert. Wirklich schlecht für die Leistung, also ist dies wahrscheinlich keine echte Option.
Verwenden Sie multi-match query: Wir würden dies tun, indem Sie dem customData-Feldnamen jedes Mal eine zufällige Zeichenfolge anhängen, wenn eine Änderung im customData-Objekt erfolgt. Zum Beispiel ist es das, was das Dokument aussehen würde indiziert:
{ "givenName": "Joe", "username": "joe", "email": "[email protected]", "customData_03ae8b95-2496-4c8d-9330-6d2058b1bbb9": { "favoriteColor": "red", "someObject": { "someKey": "someValue" } } }
a „mit der Verwendung beginnt eine neue Zuordnung für jedes‚zufällig‘Feld, und wir würden ES würde erstellen Dies bedeutet, verwenden Satz Multi-match-Abfrage "Platzhalter für die Feldnamen beim Ausführen der Abfragen. Zum Beispiel:
curl -XPOST 'eshost:9200/test/_search?pretty' -d ' { "query": { "multi_match": { "query" : "red", "type" : "phrase", "fields" : ["customData_*.favoriteColor"] } } }'
Dies könnte eine praktikable Lösung sein, aber wir sind besorgt, dass wie diese zu viele Abbildungen, die Leistung beeinträchtigen könnte. Gibt es Leistungseinbußen für zu viele Zuordnungen zu einem Index? Vielleicht könnte die periodische Neuindizierung zu viele Zuordnungen verringern?
Dies fühlt sich auch einfach wie ein Hack und etwas, das von ES nativ behandelt werden sollte. Fehle ich etwas?
Irgendwelche Vorschläge über irgendwelche davon würden sehr geschätzt.
Danke!
Sie sagen, dass verschachteltes Dokument die beschriebene nicht-deterministische Natur des 'customData' Objekts behandeln kann? –