elasticsearch - 在 Elasticsearch 中使用 SearchTemplate 和 Should 子句进行日期范围查询
问题描述
我们有一个场景,我们必须使用“OR”条件进行范围查询。它工作正常,只有一个查询,但在触发多个查询时出错。
POST _scripts/dateTemplate
{
"script": {
"lang": "mustache",
"source": """
{
"query": {
"bool": {
"must": {
"query_string": {
"query": "title:({{searchkeyword}})"
}
},
"filter": {
"bool":{
"must":[
{
"match_all": {}
}
{{#f_url}} , {
"terms" : {
"f_url": [{{#toJson}}f_url{{/toJson}} ]
}
}
{{/f_url}}
],
"should":[
{{#since}}
{
"range": {
"{{since}}": {
{{#from}}"from": "{{from}}"{{#to}},{{/to}}{{/from}}
{{#to}}"to":"{{to}}"{{/to}}
}
}
}
{{/since}}
]
}
}
}
}
}
"""
}
}
调用模板时查询
POST _search/template
{
"id": "dateTemplate",
"params": {
"searchkeyword": "*",
"since":[ {
"since":"@timestamp",
"from": "2018-06-01"
},
{
"since":"@timestamp",
"from": "2018-06-08"
}
]
}
}
错误
{
"error": {
"root_cause": [
{
"type": "json_parse_exception",
"reason": "Unexpected character ('{' (code 123)): was expecting comma to separate Array entries\n at [Source: \t\t{\n\t\t\"query\": {\n\t\t\t\"bool\": {\n\t\t\t\t\"must\": {\n\t\t\t\t\"query_string\": {\n\t\t\t\t\t\"query\": \"title:(*)\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"filter\": {\n\t\t\t\t\"bool\":{\n\t\t\t\t\t\"must\":[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"match_all\": {}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"should\":[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"range\": {\n\t\t\t\t\t\t\t\t\t\"@timestamp\": {\n\t\t\t\t\t\t\t\t\t\t\"from\": \"2018-06-01\"\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"range\": {\n\t\t\t\t\t\t\t\t\t\"@timestamp\": {\n\t\t\t\t\t\t\t\t\t\t\"from\": \"2018-06-08\"\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t}; line: 25, column: 9]"
}
],
"type": "json_parse_exception",
"reason": "Unexpected character ('{' (code 123)): was expecting comma to separate Array entries\n at [Source: \t\t{\n\t\t\"query\": {\n\t\t\t\"bool\": {\n\t\t\t\t\"must\": {\n\t\t\t\t\"query_string\": {\n\t\t\t\t\t\"query\": \"title:(*)\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"filter\": {\n\t\t\t\t\"bool\":{\n\t\t\t\t\t\"must\":[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"match_all\": {}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"should\":[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"range\": {\n\t\t\t\t\t\t\t\t\t\"@timestamp\": {\n\t\t\t\t\t\t\t\t\t\t\"from\": \"2018-06-01\"\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"range\": {\n\t\t\t\t\t\t\t\t\t\"@timestamp\": {\n\t\t\t\t\t\t\t\t\t\t\"from\": \"2018-06-08\"\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t}; line: 25, column: 9]"
},
"status": 500
}
如果我在 must 子句中添加它也是一样的,它与“AND”条件完美配合。您能帮忙用“AND”和“OR”条件构建模板吗?
解决方案
你快到了,你只需要让 mustache 知道何时到达数组的最后一个元素。所以你的模板应该是这样的(即我们在每个元素后添加一个逗号,除了最后一个):
...
"should":[
{{#since}}
{
"range": {
"{{since}}": {
{{#from}}"from": "{{from}}"{{#to}},{{/to}}{{/from}}
{{#to}}"to":"{{to}}"{{/to}}
}
}
}{{^last}},{{/last}} <-- modify this line
{{/since}}
]
...
然后只需修改您的调用以将last
标志包含到since
数组的最后一个元素中:
POST _search/template
{
"id": "dateTemplate",
"params": {
"searchkeyword": "*",
"since":[ {
"since":"@timestamp",
"from": "2018-06-01"
},
{
"since":"@timestamp",
"from": "2018-06-08",
"last": true <-- add this line
}
]
}
}
推荐阅读
- python - 使用多对多关系进行内部连接类似搜索
- javascript - 在 mouseout 停止 setInterval
- javascript - 为什么 setTimeout 返回一个数字而不是文本?反应JS
- google-api - 将谷歌驱动器文件访问权限设置为“任何拥有访问链接的人”会出现 403。如何解决?
- ruby - 我想建立话语,但我遇到了这个错误。当我在window powershell中运行'bundle exec rails s -b 0.0.0.0'时,它告诉我这个
- asp.net-mvc - 如何使用 linq 和 lambda 处理不同的服务器和不同的连接 Asp.net Web API
- vtk - 如何在不删除点或线的情况下选择性地渲染 VTK PolyData
- c++-cli - C++/CLI ref 参数重载
- python - 如何计算分割结果的 AvgD、RMSD、VOE 和 VD 评估指标?
- google-fabric - Fabric 出现了什么问题?