【问题标题】:How do I create an "OR" filter using elasticsearch-dsl-py?如何使用 elasticsearch-dsl-py 创建“OR”过滤器?
【发布时间】:2018-11-06 03:34:40
【问题描述】:

下面的查询是我想用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"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

使用elasticsearch-dsl-py,这是我能得到的最接近的,但它不一样。 '|'运算符变成了 '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()

【问题讨论】:

    标签: python elasticsearch boolean dsl


    【解决方案1】:

    使用 Elasticsearch 2.x(和 elasticsearch-dsl > 2.x),您不能再像 @theslow1 的评论那样应用过滤器了。相反,您必须通过组合 Qs 来构建您的过滤器:

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

    search.query('bool', filter=[combinedQ]) 应用 Q 标准作为过滤器,如 elasticsearch-dsl documentation 中所述。

    【讨论】:

    • 如何使用组合SF、score函数。
    • 我的 SF 将根据给定输入的大小动态变化。我将使用 for 循环来生成函数。
    【解决方案2】:

    解决方案:

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

    变成:

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

    希望将来可以将其包含在 elasticsearch-dsl-py 文档中。

    【讨论】:

    • 此解决方案已过时。 F 不再存在,过滤的语法发生了变化。
    猜你喜欢
    • 2020-12-04
    • 1970-01-01
    • 2018-10-05
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    相关资源
    最近更新 更多