【问题标题】:Elasticsearch indexed search template generates empty strings in arrayElasticsearch 索引搜索模板在数组中生成空字符串
【发布时间】:2015-07-09 11:48:05
【问题描述】:

首先,这是取自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 但不清楚,答案并没有解决我的问题(我不被允许这样存储我的模板)。

使用的 Elasticsearch 版本:1.6.0

请指教。

【问题讨论】:

    标签: elasticsearch mustache elasticsearch-template


    【解决方案1】:

    我以前见过这个要求,这个解决方案看起来很老套,但它确实有效。基本上,模板中的逗号是问题所在,因为 Mustache 将遍历数组,并且对于数组中的每个元素,都会将元素 - {{.}} - 以及您在 @987654322 中指定的 逗号 @ 和{{/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
              }
            }
          ]
        }
      }
    }
    

    【讨论】:

    • NEST 客户端在必须这样调用模板时不会有问题吗?我没有提到这个问题 - 我的错。认为会有一个简单的解决方案
    • 我不知道 :-)。我的解决方案是从 ES 的角度来看的,是的,这不是一个简单的解决方案。我花了一些时间才想出这个。
    • 想一想,为什么您认为客户应该有问题? myTerms 是一个元组数组,必须有一种方法在 NEST 中指定它。
    • 只是好奇。我会试着玩弄它。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多