在 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.
所以q
和query
不能合并。
至于“以编程方式进行范围查询”——因为您不知道您将以何种格式接收查询,标准方法是遍历查询 json、find/create 正确的 bool-must/bool-filter 并在那里设置范围查询。
但让我们退后一步——也许您的 class 一开始就不应该期待预先设置好的 JSON 查询。为什么不传递一个像
这样的查询配置数组
[
{
"type": "match_phrase",
"field": "super_cool_field",
"value": "foo"
},
...
]
并自己构建查询?这样你就可以完全控制下游传递给 ES 的内容。另外,添加日期范围查询将是小菜一碟...
我正在尝试编写一个 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 thequery
request body parameter are not returned.
所以q
和query
不能合并。
至于“以编程方式进行范围查询”——因为您不知道您将以何种格式接收查询,标准方法是遍历查询 json、find/create 正确的 bool-must/bool-filter 并在那里设置范围查询。
但让我们退后一步——也许您的 class 一开始就不应该期待预先设置好的 JSON 查询。为什么不传递一个像
这样的查询配置数组[
{
"type": "match_phrase",
"field": "super_cool_field",
"value": "foo"
},
...
]
并自己构建查询?这样你就可以完全控制下游传递给 ES 的内容。另外,添加日期范围查询将是小菜一碟...