Wenn Ihre Daten Arrays komplexer Objekte wie eine Liste von Adressen oder eine Liste von Waren enthalten, möchten Sie wahrscheinlich die Objekte nested
von elasticsearch betrachten, um Probleme zu vermeiden, wenn Ihre Abfragen mehr Elemente ergeben, als Sie erwarten würden .
Das Problem hier ist die Art, wie elasticsearch (und in der Tat Lucene) die Daten speichert. Da es kein solches Konzept von Listen verschachtelter Objekte direkt gibt, sind die Daten abgeflacht und die Verbindung zwischen z.B. XYz
und 12000
ist verloren. So würden Sie auch dieses Dokument als Ergebnis erhalten, wenn Sie für XYz
und 12500
abfragen, da der Preis von 12500
auch dort in der Liste der Werte für goods.price
ist. Um dies zu vermeiden, können Sie die Objektfunktion nested
von elasticsearch verwenden, die im Grunde alle inneren Objekte in einen versteckten Index extrahiert und die Abfrage mehrerer Felder ermöglicht, die in einem bestimmten Objekt statt "in einem der Objekte" vorkommen. Für weitere Details, werfen Sie einen Blick auf the docs on nested objects, die auch das ziemlich gut erklärt.
In Ihrem Fall könnte ein Mapping wie folgt aussehen. Ich gehe davon aus, dass Sie nur nach dem addresses.location
Text suchen möchten, ohne die ID anzugeben, damit diese Liste der einfache Objekttyp bleiben kann, anstatt auch ein verschachtelter Typ zu sein. Außerdem nehme ich an, dass Sie nach genauen Übereinstimmungen fragen. Ist dies nicht der Fall ist, müssen Sie keyword
-text
wechseln und die term
Abfrage anpassen einige match
ein ...
PUT nesting-sample
{
"mappings": {
"item": {
"properties": {
"addresses": {
"properties": {
"id": {"type": "integer"},
"location": {"type": "keyword"}
}
},
"goods": {
"type": "nested",
"properties": {
"id": {"type": "integer"},
"name": {"type": "keyword"},
"price": {"type": "integer"}
}
}
}
}
}
}
Sie dann eine Bool-Abfrage auf der location
und einer verschachtelten Abfrage verwenden können, um sein Passen Sie die inneren Dokumente Ihrer goods
Liste an.
GET nesting-sample/item/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"addresses.location": "New Delhi"
}
},
{
"nested": {
"path": "goods",
"query": {
"bool": {
"must": [
{
"range": {
"goods.price": {
"gte": 12200,
"lt": 12999
}
}
},
{
"term": {
"goods.name": {
"value": "XYz"
}
}
}
]
}
}
}
}
]
}
}
}
Diese Abfrage wird das Dokument nicht überein, da die Preisklasse wie die genaue Bezeichnung des Guten nicht in dem gleichen verschachtelten Objekt ist. Wenn Sie die untere Grenze zu 12000
ändern, wird es übereinstimmen.
Bitte überprüfen Sie Ihren Anwendungsfall und beachten Sie die Warnung unten in der Dokumentation zu the mapping explosion when using nested fields.
Ich würde vorschlagen, dass Sie die [Bool Abfrage] (https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html), [Bereich Abfrage] (https://www.elastic.co/guide/en/elasticsearch/reference/5.5/query-dsl-range-query.html) und [match] (https://www.elastic.co/guide/en/ elasticsearch/reference/5.5/query-dsl-match-query.html) oder [term query] (https://www.elastic.co/guide/en/elasticsearch/reference/5.5/query-dsl-term-query. html) – dshockley
was hast du bisher probiert? – Mysterion