简体   繁体   English

如何使用elasticsearch-dsl-py创建“OR”过滤器?

[英]How do I create an “OR” filter using elasticsearch-dsl-py?

The query below is what I would like to construct using elasticsearch-dsl-py, but I do not know how to do it. 下面的查询是我想用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"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

Using elasticsearch-dsl-py, this is as close as I can get, but it is not the same. 使用elasticsearch-dsl-py,这是我能得到的尽可能接近,但它不一样。 The '|' '|' operator is turns into 'should' clauses, instead of 'OR'. 运算符变为'should'子句,而不是'OR'。

    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()

Solution: 解:

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")]
    )

Which turns into: 哪个变成:

{  
   "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":{  

            }
         }
      }
   }
}

Hopefully this can be included in the elasticsearch-dsl-py documentation in the future. 希望将来可以将其包含在elasticsearch-dsl-py文档中。

With Elasticsearch 2.x (and elasticsearch-dsl > 2.x) you can't apply filters as in @theslow1's comment anymore. 使用Elasticsearch 2.x(和elasticsearch-dsl> 2.x),您无法再在@theslow1的注释中应用过滤器。 Instead you have to construct your filter by combining Q s: 相反,你必须通过组合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 = search.query('bool', filter=[combinedFilter])

The search.query('bool', filter=[combinedQ]) applies the Q-criteria as filter as described in the elasticsearch-dsl documentation . search.query('bool', filter=[combinedQ])将Q-criteria应用为elasticsearch-dsl文档中描述的过滤器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM