【问题标题】:ElasticSearch-dsl Create QueryElasticSearch-dsl 创建查询
【发布时间】:2019-03-14 19:29:27
【问题描述】:

大家好:

我一直在尝试使用 ElasticSearch-dsl Search() 类复制此查询,但不幸的是我无法获得它。

我要复制的查询是:

{
    "_source": {
            "includes": [ "SendingTime","Symbol","NoMDEntries","*"]
        },
        "from" : 0, "size" : 10000,
  "query": {
    "bool": {
      "must": [
        {
            "range": {
            "SendingTime": {
              "gte": "Oct 3, 2018 08:00:00 AM",
              "lt": "Oct 3, 2018 02:00:59 PM"
            }
          }
        }
      ]
    }
  }
}

日期时间最终会被变量替换。

到目前为止,我唯一能做的就是:

search = Search(using=elastic_search, index="bcs-md-bmk-prod")\
    .query("bool", range= {"SendingTime" : {'gte': format_date(datetime.now() - relativedelta(days=1)), 'lt': format_date(datetime.now())}})\

我知道我离我想要得到的东西真的很远,所以如果有人可以帮助我,我将不胜感激。

【问题讨论】:

    标签: python elasticsearch elasticsearch-dsl


    【解决方案1】:

    在 elasticsearch-dsl 中有多种方法可以构造相同的查询,这是为了方便用户,但有时(可能经常)会让新用户更加困惑。

    首先,每个原始查询和 elasticsearch-dsl 查询之间存在一对一的匹配。例如,以下是等价的:

    # 1
    'query': {
        'multi_match': {
            'query': 'whatever you are looking for',
            'fields': ['title', 'content', 'footnote']
        }
    }
    # 2
    from elasticsearch_dsl.query import MultiMatch
    MultiMatch(query='whatever you are looking for', fields=['title', 'content', 'footnote'])
    

    其次,这些对在 elasticsearh-dsl 中是等价的:

    # 1 - using a class
    from elasticsearch_dsl.query import MultiMatch
    MultiMatch(query='whatever you are looking for', fields=['title', 'content', 'footnote'])
    # 2 - using Q shortcut
    Q('multi_match', query='whatever you are looking for', fields=['title', 'content', 'footnote'])
    

    # 1 - using query type + keyword arguments 
    Q('multi_match', query='whatever your are looking for', fields=['title', 'content', 'footnote'])
    # 2 - using dict representation
    Q({'multi_match': {'query': 'whatever your are looking for', 'fields': ['title', 'content', 'footnote']}})
    

    # 1 - using Q shortcut
    q = Q('multi_match', query='whatever your are looking for', fields=['title', 'content', 'footnote'])
    s.query(q)
    # 2 - using parameters for Q directly
    s.query('multi_match', query='whatever your are looking for', fields=['title', 'content', 'footnote'])
    

    现在,如果我们回忆一下bool query 的结构,它由布尔子句组成,每个子句都有一个“类型化的出现”(must、should、must_not 等)。由于每个子句也是一个“查询”(在您的情况下为 range query),它遵循与“查询”相同的模式,这意味着它可以用 Q 快捷方式表示。

    所以,我构建您的查询的方式是:

    search = Search(using=elastic_search, index="bcs-md-bmk-prod")
              .query(Q('bool', must=[Q('range', SendingTime={"gte": "Oct 3, 2018 08:00:00 AM", "lt": "Oct 3, 2018 02:00:59 PM"})]))
              .source(includes=["SendingTime","Symbol","NoMDEntries","*"])
    

    请注意,为简单起见,可以删除第一个 Q,使该行:

    .query('bool', must=[Q('range', SendingTime={"gte": "Oct 3, 2018 08:00:00 AM", "lt": "Oct 3, 2018 02:00:59 PM"})])
    

    但我会保留它以便更容易理解。随意在不同的表示之间进行权衡。

    最后但同样重要的是,当您在 elasticsearch-dsl 中构造查询有困难时,您始终可以使用 elasticsearch_dsl.Search 类的 from_dict() 方法回退到原始 dict 表示。

    【讨论】:

      猜你喜欢
      • 2018-10-17
      • 1970-01-01
      • 2022-12-15
      • 2021-02-08
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      • 2021-11-15
      • 1970-01-01
      相关资源
      最近更新 更多