2014-04-02 7 views
11

Meine Filter sind in Kategorien zusammengefasst. Ich möchte Dokumente abrufen, in denen ein Dokument mit einem Filter in einer Kategorie übereinstimmen kann. Wenn jedoch zwei (oder mehr) Kategorien festgelegt sind, muss das Dokument mit allen Filtern in ALLEN Kategorien übereinstimmen.Wie verschachtelte AND- und OR-Filter in ElasticSearch?

Wenn in pseudo-SQL geschrieben wäre es:

SELECT * FROM Documents WHERE (CategoryA = 'A') AND (CategoryB = 'B' OR CategoryB = 'C') 

I Verschachtelte Filter wie so versucht haben:

{ 
    "sort": [{ 
     "orderDate": "desc" 
    }], 
    "size": 25, 
    "query": { 
     "match_all": {} 
    }, 
    "filter": { 
     "and": [{ 
      "nested": { 
       "path":"hits._source", 
       "filter": { 
        "or": [{ 
         "term": { 
          "progress": "incomplete" 
         } 
        }, { 
         "term": { 
          "progress": "completed" 
         } 
        }] 
       } 
      } 
     }, { 
      "nested": { 
       "path":"hits._source", 
       "filter": { 
        "or": [{ 
         "term": { 
          "paid": "yes" 
         } 
        }, { 
         "term": { 
          "paid": "no" 
         } 
        }] 
       } 
      } 
     }] 
    } 
} 

aber offenbar noch recht ich nicht die ES-Syntax verstehen. Ist das auf dem richtigen Weg oder muss ich einen anderen Filter verwenden?

+0

nicht die Antwort im Zusammenhang auf die Frage: '' '' '' '' mit '' term'' kann mit [terms] einfacher gemacht werden (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-terms- filter.html). und der Standard für [bool] (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html) ist '' and''. etwas an '' filter.bool.must: [{terms: progress: ["incomplete", "complete"]}. {Begriffe: bezahlt: ["ja", "nein"]}] "könnte funktionieren? – cfrick

+0

verschachtelte Abfragen/Filter werden für Arrays/Listen verwendet (abhängig davon, mit welcher Sprache Sie vertraut sind, z. B. 'a = [{'b': 1}, {'c': 2}])' '. Könnten Sie ein Beispiel für eines Ihrer Dokumente schreiben? Das würde helfen – Diolor

+0

cfrick hat mich auf den richtigen Weg gebracht. Ich habe eine Reihe von "Terms" -Filtern in einem "und" Filter verschachtelt, und es scheint meine Bedürfnisse zu erfüllen. – MHTri

Antwort

3

Obwohl ich Ihre Struktur nicht vollständig verstanden habe, könnte dies das sein, was Sie brauchen.

Sie müssen Baum-weise denken. Sie erstellen eine Bool, wo Sie die eingebetteten Bools (= und) erfüllen müssen. Jedes eingebettete Element prüft, ob das Feld nicht existiert oder sonst (hier sollte anstelle von muss verwendet werden). Das Feld muss (Begriffe hier) einer der Werte in der Liste sein.

Nicht sicher, ob es einen besseren Weg gibt, und kenne die Leistung nicht.

{ 
    "sort": [ 
     { 
      "orderDate": "desc" 
     } 
    ], 
    "size": 25, 
    "query": { 
     "query": {   # 
      "match_all": {} # These three lines are not necessary 
     },     # 
     "filtered": { 
      "filter": { 
       "bool": { 
        "must": [ 
         { 
          "bool": { 
           "should": [ 
            { 
             "not": { 
              "exists": { 
               "field": "progress" 
              } 
             } 
            }, 
            { 
             "terms": { 
              "progress": [ 
               "incomplete", 
               "complete" 
              ] 
             } 
            } 
           ] 
          } 
         }, 
         { 
          "bool": { 
           "should": [ 
            { 
             "not": { 
              "exists": { 
               "field": "paid" 
              } 
             } 
            }, 
            { 
             "terms": { 
              "paid": [ 
               "yes", 
               "no" 
              ] 
             } 
            } 
           ] 
          } 
         } 
        ] 
       } 
      } 
     } 
    } 
} 
+2

Das ist falsch. "müssen" und "sollten" sind keine Aliasnamen für "und" und "oder". Sie haben unterschiedliche Funktionen (obwohl es Ähnlichkeiten gibt) –

8

Dieses es

(aus gegebenen Pseudo-SQL übersetzt) ​​sein sollte
{ 
    "sort": [ 
     { 
     "orderDate": "desc" 
     } 
    ], 
    "size": 25, 
    "query": 
    { 
     "filtered": 
     { 
      "filter": 
      { 
       "and": 
       [ 
        { "term": { "CategoryA":"A" } }, 
        { 
         "or": 
         [ 
          { "term": { "CategoryB":"B" } }, 
          { "term": { "CategoryB":"C" } } 
         ] 
        } 
       ] 
      } 
     } 
    } 
} 

Ich weiß, Sie sind nicht Facetten zu erwähnen, sondern nur aus Gründen der Vollständigkeit halber:

Sie auch nutzen könnten eine filter als Basis (wie Sie) anstelle einer filtered query (wie ich). Das resultierende json ist fast identisch mit dem Unterschied,:

  • eine gefilterte Abfrage filtert sowohl die wichtigsten Ergebnisse sowie Facetten
  • ein Filter werden nur die wichtigsten Ergebnisse Filter nicht die Facetten.

Schließlich Verschachtelte Filter (die Sie versucht mit) beziehen sich nicht auf ‚Verschachtelung Filter‘ wie Sie zu glauben schien, aber das Filtern auf verschachtelte Dokumente (Eltern-Kind)

Verwandte Themen