在 Elasticsearch 中混合 DSL 和 URI 查询

Mix DSL and URI query in Elasticsearch

我正在尝试编写一个 python class,它将格式正确的 Elasticsearch JSON 查询作为参数。到目前为止一切顺利。但是,作为 class 的一部分,我还想使用“to”和“from”参数来限制查询运行的日期范围。

有没有办法将 DSL 查询的 JSON 与 URI 参数结合起来以传递日期和时间限制?

我知道我可以使用这样的范围参数来限制时间:

GET /my-awesome-index*/_search
{
    "query": 
    {
        "bool": 
        {
            "must": [{"match_all": {}}],
            "filter": 
            [
                {"range": {"date_time": {"gte": "now-24h","lte": "now"}}},
                {"match_phrase": {"super_cool_field": "foo"}},
                {
                    "bool": 
                    {
                        "should": 
                        [
                            {"match_phrase": {"somewhat_cool_field_1": "bar"}},
                            {"match_phrase": {"somewhat_cool_field_2": "boo-ta"}}
                        ],
                        "minimum_should_match": 1
                    }
                }
            ]
        }
    }
}

这一切都很好.. 但是,我想制作我的 class 使时间范围成为一个变量。我也知道我可以通过像这样提交 URL 来限制时间范围..

GET /my-awesome-index*/_search?q=date_time:[1611732033412+TO+1611777796000]
{
    "query": 
    {
        "bool": 
        {
            "must": [{"match_all": {}}],
            "filter": 
            [
                {"match_phrase": {"super_cool_field": "foo"}},
                {
                    "bool": 
                    {
                        "should": 
                        [
                            {"match_phrase": {"somewhat_cool_field_1": "bar"}},
                            {"match_phrase": {"somewhat_cool_field_2": "boo-ta"}}
                        ],
                        "minimum_should_match": 1
                    }
                }
            ]
        }
    }
}

然而,当我提交时,Elasticsearch 似乎只考虑 URI 的时间范围,完全忽略 DSL JSON。

有没有办法让 Elastic 考虑/将两个查询合并为一个?

我正在考虑以编程方式使范围查询类似于这样

range_part = '{{"range":{{"{}":{{"gte":"{}","lte":"{}"}}}}}}'.format(field,start,end)

然后动态插入到任何 JSON 中 class 需要..但这看起来很麻烦,因为有太多的格式可用于查询和查找放置字符串的位置等..

你对q的怀疑是对的。引用自 docs:

The q parameter overrides the query parameter in the request body. If both parameters are specified, documents matching the query request body parameter are not returned.

所以qquery不能合并。

至于“以编程方式进行范围查询”——因为您不知道您将以何种格式接收查询,标准方法是遍历查询 json、find/create 正确的 bool-must/bool-filter 并在那里设置范围查询。

但让我们退后一步——也许您的 class 一开始就不应该期待预先设置好的 JSON 查询。为什么不传递一个像

这样的查询配置数组
[
  {
    "type": "match_phrase",
    "field": "super_cool_field",
    "value": "foo"
  },
  ...
]

并自己构建查询?这样你就可以完全控制下游传递给 ES 的内容。另外,添加日期范围查询将是小菜一碟...