Elasticsearch Mustache 可选参数
Elasticsearch Mustache optional parameters
我一直在努力使用 Elasticsearch 模板,特别是在可选参数方面。我想在那里添加 optional 过滤器。这是我正在尝试的代码片段:
{
"filter" : {
"bool" : {
"must" : [
{{#ProductIDs.0}}
{ "terms" : { "Product.ProductID" : [{{#ProductIDs}}{{.}},{{/ProductIDs}}] } }
{{/ProductIDs.0}}
]
}
}
}
当然我把"
换成\"
,丑化了,包在{ "template" :"_snippet_above_" }
.
现在,当我尝试使用以下方式调用它时:
GET /statistic/_search/template
{
"template": {
"id": "test"
},
"params": {
"ProductIDs": [1,2]
}
}
它忽略了我提供的参数,但是当我尝试在官方 mustache.io 演示页面中这样做时 - 它工作得很好。
我也尝试了 {{#ProductIDs.length}}
选项 - 但没有成功。在做了一些研究之后,我发现 mustache.js 和 mustache.java 之间有一个区别。我假设 Elasticsearch 使用 JAVA 版本并且它不支持长度参数,所以我必须依赖 isEmpty。所以我重写了我的查询如下:
{
"filter" : {
"bool" : {
"must" : [
{{^ProductIDs.isEmpty}}
{ "terms" : { "Product.ProductID" : [{{#ProductIDs}}{{.}},{{/ProductIDs}}] } }
{{/ProductIDs.isEmpty}}
]
}
}
}
现在,当我使用 ProductIDs 列表查询模板时 - 它工作正常,但是如果我删除参数,则不会产生任何结果。我假设它会产生这个:
{
"filter" : {
"bool" : {
"must" : [
{ "terms" : { "Product.ProductID" : [] } }
]
}
}
}
如果我发送空数组作为参数 - 它工作正常。
GET /statistic/_search/template
{
"template": {
"id": "test"
},
"params": {
"ProductIDs": []
}
}
我假设发生这种情况是因为 "ProductIDs"
是 undefined
而不是空的。
有没有办法在 mustache.java 中包含此条件,以便我可以忽略这些参数?
tl;博士;
问题是,如果我没有通过模板在我的搜索请求中指定参数,我的条件将呈现为一个空数组,请参见:
{
"filter" : {
"bool" : {
"must" : [
{ "terms" : { "Product.ProductID" : [] } }
]
}
}
}
如果我将空数组作为参数传递,请参见:
GET /statistic/_search/template
{
"template": {
"id": "test"
},
"params": {
"ProductIDs": []
}
}
它按预期工作,并没有像我的模板中描述的那样生成过滤条件,因为数组中没有任何数据。
我想要这个:
GET /statistic/_search/template
{
"template": {
"id": "test"
},
"params": {
}
}
要像这样工作:
GET /statistic/_search/template
{
"template": {
"id": "test"
},
"params": {
"ProductIDs": []
}
}
可能不是最优雅的解决方法是将模板查询更改为 should
子句并为空列表添加 match_all
子句。
示例:
{
"filter" : {
"bool" : {
"should" : [
{ "terms" : { "status" : [ "{{#ProductIDs}}","{{.}}","{{/ProductIDs}}"] }}
{{^ProductIDs}},
{"match_all":{}}
{{/ProductIDs}}
]
}
}
}
没试过,但这样的东西不应该有用吗?
{
"filter" : {
"bool" : {
"must" : [
{{#ProductIDs}}
{{^ProductIDs.isEmpty}}
{ "terms" : { "Product.ProductID" : [{{#ProductIDs}}{{.}},{{/ProductIDs}}] } }
{{/ProductIDs.isEmpty}}
{{#ProductIDs.isEmpty}}
{"match_all":{}}
{{/ProductIDs.isEmpty}}
{{/ProductIDs}}
{{^ProductIDs}}
{"match_all":{}}
{{/ProductIDs}}
]
}
}
}
不太好,也许有更好的方法。
我建议使用 JSON 模板来解决这个问题:
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"inline": "1==1 {{#ProductIDs}} && [\"{{#ProductIDs}}\",\"{{.}}\",\"{{/ProductIDs}}\"].contains(doc['Product.ProductID'].value){{/ProductIDs}}",
"lang": "painless"
}
}
}
]
}
}
我一直在努力使用 Elasticsearch 模板,特别是在可选参数方面。我想在那里添加 optional 过滤器。这是我正在尝试的代码片段:
{
"filter" : {
"bool" : {
"must" : [
{{#ProductIDs.0}}
{ "terms" : { "Product.ProductID" : [{{#ProductIDs}}{{.}},{{/ProductIDs}}] } }
{{/ProductIDs.0}}
]
}
}
}
当然我把"
换成\"
,丑化了,包在{ "template" :"_snippet_above_" }
.
现在,当我尝试使用以下方式调用它时:
GET /statistic/_search/template
{
"template": {
"id": "test"
},
"params": {
"ProductIDs": [1,2]
}
}
它忽略了我提供的参数,但是当我尝试在官方 mustache.io 演示页面中这样做时 - 它工作得很好。
我也尝试了 {{#ProductIDs.length}}
选项 - 但没有成功。在做了一些研究之后,我发现 mustache.js 和 mustache.java 之间有一个区别。我假设 Elasticsearch 使用 JAVA 版本并且它不支持长度参数,所以我必须依赖 isEmpty。所以我重写了我的查询如下:
{
"filter" : {
"bool" : {
"must" : [
{{^ProductIDs.isEmpty}}
{ "terms" : { "Product.ProductID" : [{{#ProductIDs}}{{.}},{{/ProductIDs}}] } }
{{/ProductIDs.isEmpty}}
]
}
}
}
现在,当我使用 ProductIDs 列表查询模板时 - 它工作正常,但是如果我删除参数,则不会产生任何结果。我假设它会产生这个:
{
"filter" : {
"bool" : {
"must" : [
{ "terms" : { "Product.ProductID" : [] } }
]
}
}
}
如果我发送空数组作为参数 - 它工作正常。
GET /statistic/_search/template
{
"template": {
"id": "test"
},
"params": {
"ProductIDs": []
}
}
我假设发生这种情况是因为 "ProductIDs"
是 undefined
而不是空的。
有没有办法在 mustache.java 中包含此条件,以便我可以忽略这些参数?
tl;博士; 问题是,如果我没有通过模板在我的搜索请求中指定参数,我的条件将呈现为一个空数组,请参见:
{
"filter" : {
"bool" : {
"must" : [
{ "terms" : { "Product.ProductID" : [] } }
]
}
}
}
如果我将空数组作为参数传递,请参见:
GET /statistic/_search/template
{
"template": {
"id": "test"
},
"params": {
"ProductIDs": []
}
}
它按预期工作,并没有像我的模板中描述的那样生成过滤条件,因为数组中没有任何数据。
我想要这个:
GET /statistic/_search/template
{
"template": {
"id": "test"
},
"params": {
}
}
要像这样工作:
GET /statistic/_search/template
{
"template": {
"id": "test"
},
"params": {
"ProductIDs": []
}
}
可能不是最优雅的解决方法是将模板查询更改为 should
子句并为空列表添加 match_all
子句。
示例:
{
"filter" : {
"bool" : {
"should" : [
{ "terms" : { "status" : [ "{{#ProductIDs}}","{{.}}","{{/ProductIDs}}"] }}
{{^ProductIDs}},
{"match_all":{}}
{{/ProductIDs}}
]
}
}
}
没试过,但这样的东西不应该有用吗?
{
"filter" : {
"bool" : {
"must" : [
{{#ProductIDs}}
{{^ProductIDs.isEmpty}}
{ "terms" : { "Product.ProductID" : [{{#ProductIDs}}{{.}},{{/ProductIDs}}] } }
{{/ProductIDs.isEmpty}}
{{#ProductIDs.isEmpty}}
{"match_all":{}}
{{/ProductIDs.isEmpty}}
{{/ProductIDs}}
{{^ProductIDs}}
{"match_all":{}}
{{/ProductIDs}}
]
}
}
}
不太好,也许有更好的方法。
我建议使用 JSON 模板来解决这个问题:
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"inline": "1==1 {{#ProductIDs}} && [\"{{#ProductIDs}}\",\"{{.}}\",\"{{/ProductIDs}}\"].contains(doc['Product.ProductID'].value){{/ProductIDs}}",
"lang": "painless"
}
}
}
]
}
}