2017-12-19 2 views
0

ich einen Elasticsearch Index mit den folgenden Zuordnungen haben:Elasticsearch UND-Verknüpfung auf complexObjektFelder

{ 
"index_one": { 
    "mappings": { 
     "uidMapping": { 
      "_all": { 
       "enabled": false 
      }, 
      "_source": { 
       "enabled": false 
      }, 
      "properties": { 
       "age": { 
        "type": "keyword" 
       }, 
       "clean_url": { 
        "type": "keyword", 
        "index": false, 
        "fields": { 
         "hash": { 
          "type": "murmur3" 
         } 
        } 
       }, 
       "gender": { 
        "type": "keyword" 
       }, 
       "segment_aggregate": { 
        "properties": { 
         "segment_name": { 
          "type": "keyword" 
         }, 
         "segment_value": { 
          "type": "keyword" 
         } 
        } 
       }, 
       "url_md5": { 
        "type": "keyword", 
        "index": false 
       }, 
       "url_page_views": { 
        "type": "integer", 
        "index": false 
       } 
      } 
     } 
    } 
} 
} 

Ich versuche, Abfragen mit einer UND-Verknüpfung auf den segment_aggregate Felder zu laufen, das heißt, sollten Abfragen Ergebnisse nur sein zurückgegeben, wenn beide Bedingungen erfüllt sind. Bisher habe ich mit BoolQueryBuilders versucht, Match-Abfragen und Terme in Must-Klauseln abzufragen, aber es scheint immer, Ergebnisse mit einer oder -Operation zwischen segment_name und segment_value zu erhalten.

BoolQueryBuilder queryTest = new BoolQueryBuilder(); 
queryTest.must(QueryBuilders.matchQuery("segment_aggregate.segment_name", 
"AnyValue").operator(Operator.AND)); 

queryTest.must(QueryBuilders.matchQuery("segment_aggregate.segment_value", 
"A").operator(Operator.AND)); 

parentQuery.must(queryTest); 

Dies gibt ein OR-Ergebnis für die beiden Felder zurück, im Grunde die größere Teilmenge. auch versucht:

mustQuery.must(QueryBuilders.termsQuery("segment_aggregate.segment_name", "SegmentName")); 
mustQuery.must(QueryBuilders.termsQuery("segment_aggregate.segment_value", "SegmentValue")); 

Auch dies ergibt keine Wünsche Ergebnisse. Auch wenn ich versuchte, die Unterabfragen mit must-Klauseln in einer anderen Abfrage zu umhüllen und zur übergeordneten Abfrage hinzuzufügen, funktionierte dieser Ansatz ebenfalls nicht.

Irgendwelche Ideen, wo ich falsch liege?

Antwort

1

Das Problem, das Sie sehen, liegt wahrscheinlich daran, dass Sie den Typ segment_aggregate nicht als verschachtelt markieren.

Standardmäßig sind alle Felder unabhängig voneinander indiziert. Obwohl die JSON-Struktur aussieht, als würden Sie innerhalb des inneren Objekts in segment_aggregate spezifische Werte zuordnen, erstellt ES tatsächlich einen Index der Werte für segment_aggregate.segmentname und einen separaten Index für segment_aggregate.segment_value.

Das bedeutet, wenn Sie eine Suche wie dieses (unter der Annahme, Abfrage-String) tun:

segment_aggregate.segment_name:color AND segment_aggregate.segment_value:green 

was Elasticsearch wirklich für ein Dokument sucht tut wo ANY des Wertes in segment_aggregate.segment_name auf "color" und ANY der Werte in segment_aggregate.segment_value sind auf "grün" gesetzt. Um Elasticsearch mitzuteilen, dass Sie die Zuordnung zwischen den Feldern im inneren Objekt verwenden möchten, müssen Sie segment_aggregate Typ als "verschachtelt" anstelle der Vorgabe von "Objekt" markieren. Außerdem müssen Sie die speziellen geschachtelten Abfrage- und verschachtelten Aggregationsteile der Abfrage-DSL verwenden.

Weitere Details finden Sie hier: https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html

+0

Hallo Ryan, dachte ich es auch, aber als ich versuchte, so etwas wie: QueryBuilders.nestedQuery ("segment_aggregate", // Pfad \t \t \t \t \t \t QueryBuilders.boolQuery() // Ihre Anfrage \t \t \t \t \t \t \t \t .must (QueryBuilders.matchQuery ("segment_aggregate.segment_name" Segmentname) ) \t \t \t \t \t \t \t \t .must (QueryBuilders.matchQuery ("segment_aggregate.segment_value“, "A"))) \t \t \t \t \t \t .scoreMode ("max");. Elasticsearch warf Ausnahmen Benötige ich Mappings auch für den Index ändern –

+0

Ja, Sie brauchen? um den Typ im Mapping von segment_aggregate explizit auf "nested" zu setzen. – RyanW

+0

Akzeptierte Antwort. Funktioniert gut, nachdem Indexzuordnungen geändert wurden. –