2015-07-28 6 views
9

Was ich erreichen möchte: Ich möchte, dass meine "Alter" -Aggregation nicht vom Abfragefilter gefiltert wird und ich Filter anwenden kann.Wie filtere ich eine globale Aggregation von elasticsearch?

Also, wenn ich mit dieser Abfrage starten:

{ 
    "query":{ 
     "filtered":{ 
      "filter":{ "terms":{ "family_name":"Brown" } } //filter_1 
     } 
    }, 
    "aggs":{ 
     "young_age":{ 
      "filter":{ 
       "range":{ "lt":40, "gt":18 } //filter_2 
      }, 
      "aggs":{ 
       "age":{ 
        "terms":{ 
         "field":"age" 
        } 
       } 
      } 
     } 
    } 
} 

Meine Aggregation "young_age" wird sowohl von filter_1 und filter_2 gefiltert werden. Ich möchte nicht, dass meine Aggregation nach filter_1 gefiltert wird.

Als ich in der Dokumentation suchen, dachte ich globale Aggregation mein Problem lösen würde, und ich schrieb, dass die Abfrage:

{ 
    "query":{ 
     "filtered":{ 
      "filter":{ "terms":{ "family_name":"Brown" } } //filter_1 
     } 
    }, 
    "aggs":{ 
     "young_age":{ 
      "global":{}, //<----------- add global 
      "filter":{ 
       "range":{ "lt":40, "gt":18 } //filter_2 
      }, 
      "aggs":{ 
       "age":{ 
        "terms":{ 
         "field":"age" 
        } 
       } 
      } 
     } 
    } 
} 

Aber dann Elasticsearch beschwert sich über meine filter_2:

„““ gefunden zwei Aggregationstyp-Definitionen [Alter] in [global] und [Filter] ""“

und natürlich, wenn ich entfernen Sie die filter_2:

{ 
    "query":{ 
     "filtered":{ 
      "filter":{ 
       "terms":{ 
        "family_name":"Brown" 
       } 
      } 
     } 
    }, 
    "aggs":{ 
     "young_age":{ 
      "global":{}, 
      "aggs":{ 
       "age":{ 
        "terms":{ 
         "field":"age" 
        } 
       } 
      } 
     } 
    } 
} 

Dann wird meine Aggregation nicht von filter_1 gefiltert (wie erwartet).

Also, wie soll ich Filter_2 auf meine globale Aggregation anwenden? Oder wie soll ich das erreichen? Ich erinnere mich, etwas ähnliches mit den Facettenfiltern geschrieben zu haben ...

Antwort

2

Meiner Meinung nach ist dies der typische Anwendungsfall eines post_filter. Wie der doc sagt:

Die post_filter angewendet wird, um die Suche am Ende einer Suchanfrage trifft, haben nach Aggregationen bereits

Ihre Anfrage aussehen wird berechnet:

{ 
    "post_filter":{ 
     "terms":{ 
      "family_name":"Brown" //filter_1 
     } 
    }, 
    "aggs":{ 
     "young_age":{ 
      "filter":{ 
       "range":{ "lt":40, "gt":18 } //filter_2 
      }, 
      "aggs":{ 
       "age":{ 
        "terms":{ 
         "field":"age" 
        } 
       } 
      } 
     } 
    } 
} 

In diesem Fall sind die Suchtreffer alle Dokumente im Index. Dann wird die Aggregation berechnet (vor Filter_1). Und danach wird die post_filter mit dem Filter_1 ausgeführt.

Edit: Wie Sie in Ihrem commend sagte haben Sie viele Aggregationen und nur eine, die nicht von filter_1 betroffen sein sollte ich feste Abfrage globale Aggregation mit

{ 
    "query": { 
    "filtered": { 
     "filter": { 
     "term": { 
      "family_name": "Brown" 
     } 
     } 
    } 
    }, 
    "aggs": { 
    "young_age": { 
     "global": {}, 
     "aggs": { 
     "filter2": { 
      "filter": { 
      "range": { 
       "lt": 40, 
       "gt": 18 
      } 
      }, 
      "aggs": { 
      "age": { 
       "terms": { 
       "field": "age" 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 
+1

, die funktionieren würde, aber eigentlich habe ich viele bekam Aggregationen und nur eine davon sollte nicht durch filter_1 gefiltert werden. Also mit Ihrer Lösung bedeutet das, dass ich den post_filter für jene Aggregationen replizieren müsste, die ich ein wenig nervig finde (und vielleicht auch nicht so gut aus der Sicht der Leistung?) – adrienbourgeois

+1

@adrienbourgeois Ich habe die Abfrage mit globaler Aggregation behoben, lassen Ich weiß, ob es für Sie funktioniert :) – moliware

+0

Dank mate funktioniert es wie ein Charme! Ich habe deine Antwort akzeptiert. Prost – adrienbourgeois