Elasticsearch索引搜索模板在数组中生成空字符串

时间:2015-07-09 11:48:06

标签: elasticsearch mustache elasticsearch-template

首先,这取自documentation

  

传递字符串数组

GET /_search/template
{
  "template": {
    "query": {
      "terms": {
        "status": [
          "{{#status}}",
          "{{.}}",
          "{{/status}}"
        ]
      }
    }
  },
  "params": {
    "status": [ "pending", "published" ]
  }
}
     

呈现为:

{
"query": {
  "terms": {
    "status": [ "pending", "published" ]
  }
}

然而,在我的场景中,我完成了相同的模板(至少我是这么认为的),但它为我产生了略微不同的输出:

.."filter" : {
  "bool" : {
    "must" : [{
        "terms" : {
          "myTerms" : [
            "{{#myTerms}}",
            "{{.}}",
            "{{/myTerms}}"
          ],
          "_cache" : true
        }
      }
    ]
  }
}..

我以后称之为:

GET /passport/_search/template
{
    "template": {
        "id": "myTemplate" 
    },
    "params": {
        "myTerms": ["1", "2"]
    }
}

然而它呈现为:

.."myTerms" : ["", "1", "2", ""]..

这不会是一个问题,但myTerms存储为整数,我想保持这种方式(但如果这只是解决方案,那么很好,我可以忍受它),但随后查询抛出异常它不能将“”转换为整数类型,这是预期的行为

  

NumberFormatException [输入字符串:\“\”]

我该如何处理?我不想将模板存储为文件,我更喜欢将它们编入索引。

这个SO问题很有希望:Pass an array of integers to ElasticSeach template但不清楚,答案没有解决我的问题(我不允许存储我的模板)。

使用的弹性版本:1.6.0

请建议。

1 个答案:

答案 0 :(得分:2)

之前我已经看过这个要求而且解决方案看起来很糟糕,但它确实有效。基本上,模板中的逗号是问题,因为Mustache将遍历数组,并且对于数组中的每个元素,将放置元素 - {{.}} - 以及您在内部指定的逗号 {{#myTerms}}{{/myTerms}}

而且,在您的情况下您不应该使用双引号 - "{{.}}",因为元素本身将被双引号括起来。这就是您在结果中看到"1"的原因。但是,如果你想匹配数字列表,而不是字符串。

所以,首先,摆脱双引号。这意味着,用双引号包围模板并转义任何应该在最终结果中出现的双引号(通过查看下面的示例,您将很快理解)。

其次,hacky部分是模拟结果中的逗号并跳过最后一个逗号。含义,1,2,3,不应包含最后一个逗号。解决方案是将参数作为元组列表提供 - 元组的一个元素是值本身,另一个元素是布尔值:[{"value":1,"comma":true},{"value":2,"comma":true},{"value":4}]。如果commatrue,那么Mustache应该放,,否则不放(这种情况是针对数组中的最后一个元素)。

POST /_search/template/myTemplate
{"template":"{\"filter\":{\"bool\":{\"must\":[{\"terms\":{\"myTerms\":[{{#myTerms}}{{value}}{{#comma}},{{/comma}}{{/myTerms}}],\"_cache\":true}}]}}}"}

这就是你应该如何传递参数:

{
  "template": {
    "id": "myTemplate"
  },
  "params": {
    "myTerms": [{"value":1,"comma":true},{"value":2,"comma":true},{"value":4}]
  }
}

这样做是为了生成这样的东西:

{
  "filter": {
    "bool": {
      "must": [
        {
          "terms": {
            "myTerms": [1,2,4],
            "_cache": true
          }
        }
      ]
    }
  }
}