2015-02-17 7 views
7

Die Abfrage unten ist, was ich mit elasticsearch-dsl-py konstruieren möchte, aber ich weiß nicht, wie es geht.Wie erstelle ich einen "OR" -Filter mit elasticsearch-dsl-py?

GET /my_index/_search 
{ 
    "query": { 
    "filtered": { 
     "filter": { 
     "bool": { 
      "must": [ 
      { 
       "term": { 
       "status": "published" 
       } 
      }, 
      { 
       "or": { 
       "filters": [ 
        { 
        "range": { 
         "start_publication": { 
         "lte": "2015-02-17T03:45:00.245012+00:00" 
         } 
        } 
        }, 
        { 
        "missing": { 
         "field": "start_publication" 
        } 
        } 
       ] 
       } 
      }, 
      { 
       "or":{ 
       "filters": [ 
        { 
        "range": { 
         "end_publication": { 
         "gte": "2015-02-17T03:45:00.245012+00:00" 
         } 
        } 
        }, 
        { 
        "missing": { 
         "field": "end_publication" 
        } 
        } 
       ] 
       } 
      } 
      ] 
     } 
     } 
    } 
    } 
} 

Mit Elasticsearch-dsl-py, dann ist dies so nah wie ich bekommen kann, aber es ist nicht das gleiche. Das '|' Der Operator wird anstelle von "ODER" zu "Soll" -Klauseln.

client = Elasticsearch() 
    now = timezone.now() 

    s = Search(using=client, 
       index="my_index" 
     ).filter(
      "term", status=PUBLISHED 
     ).filter(
      F("range", start_publication={"lte": now},) | 
      F("missing", field="start_publication") 
     ).filter(
      F("range", end_publication={"gte": now},) | 
      F("missing", field="end_publication") 
     ) 
    response = s.execute() 

Antwort

9

Lösung:

s = Search(using=client, 
      index="my_index" 
    ).filter(
     "term", status=PUBLISHED 
    ).filter(
     "or", [F("range", start_publication={"lte": now},), 
       F("missing", field="start_publication")] 
    ).filter(
     "or", [F("range", end_publication={"gte": now},), 
       F("missing", field="end_publication")] 
    ) 

die in dreht:

{ 
    "query":{ 
     "filtered":{ 
     "filter":{ 
      "bool":{ 
       "must":[ 
        { 
        "term":{ 
         "status":"published" 
        } 
        }, 
        { 
        "or":{ 
         "filters":[ 
          { 
           "range":{ 
           "start_publication":{ 
            "lte":"2015-02-17T03:45:00.245012+00:00" 
           } 
           } 
          }, 
          { 
           "missing":{ 
           "field":"start_publication" 
           } 
          } 
         ] 
        } 
        }, 
        { 
        "or":{ 
         "filters":[ 
          { 
           "range":{ 
           "end_publication":{ 
            "gte":"2015-02-17T03:45:00.245012+00:00" 
           } 
           } 
          }, 
          { 
           "missing":{ 
           "field":"end_publication" 
           } 
          } 
         ] 
        } 
        } 
       ] 
      } 
     }, 
     "query":{ 
      "match_all":{ 

      } 
     } 
     } 
    } 
} 

Hoffentlich kann dies in Zukunft in der Elasticsearch-dsl-py Dokumentation enthalten sein.

+1

Diese Lösung ist veraltet. F existiert nicht mehr und die Syntax zum Filtern wurde geändert. – Michael

2

Mit Elasticsearch 2.x (und elasticsearch-dsl> 2.x) können Sie keine Filter wie in @ theslow1's Kommentar mehr anwenden. Stattdessen müssen Sie Ihre Filter konstruieren durch die Kombination von Q s:

search = Search(using=esclient, index="myIndex") 
firstFilter = Q("match", color='blue') & Q("match", status='published') 
secondFilter = Q("match", color='yellow') & Q("match", author='John Doe') 
combinedFilter = firstFilter | secondFilter 
search.query('bool', filter=[combinedFilter]) 

Die search.query('bool', filter=[combinedQ]) gilt die Q-Kriterien als Filter wie in der elasticsearch-dsl documentation beschrieben.

+0

Wie kombiniere ich SF, Score-Funktion. – devanathan

+0

Mein SF wird basierend auf der Größe der Eingabe dynamisch sein. Ich werde die for-Schleife verwenden, um die Funktionen zu generieren. – devanathan