字符串范围查询[弹性搜索]

时间:2020-04-21 01:53:27

标签: elasticsearch range

我有一个具有相同键的JSON对象。

这些值可以是字符串或数字(以字符串形式),并且在弹性搜索中以相同的方式被索引为文本

[{
  "key" : "foo",
  "value" : "lisa"
}, {
  "key" : "bar",
  "value" : "19"
}]

我正在根据以下条件进行比较:

1. match key as "bar"
2. range { "value" : {gt:"10"}}

这没有发生,因为该值被索引为字符串(应为字符串),并且由于字符串“ 2”>字符串“ 10”,因此失败-这是预期的。

关于如何解决此用例的任何建议?

其他信息

我发现删除了有关在Elastic Search 7.0+中用作TermRangeQuery的字符串的文档。

参考

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html

2 个答案:

答案 0 :(得分:2)

您已经遇到过,未使用正确的数据类型的缺点会导致意外的行为。我安静地不明白为什么值可以是数字字符串等。但是考虑到用例,我建议为不同类型的值定义不同的字段。考虑要与之匹配的查询,需要保持键和值字段之间的关系。因此,我建议您定义一个嵌套字段而不是普通对象字段。

不使用对象字段的原因是elastisearch将对象展平,然后对其进行索引。展平对象会导致属性之间的关系丢失。进一步了解此here

现在,考虑以下示例(弹性7.x):

步骤1:为字段定义具有正确类型的映射

PUT test
{
  "mappings": {
    "properties": {
      "nestedField": {
        "type": "nested",
        "properties": {
          "key": {
            "type": "keyword"
          },
          "stringValue": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword"
              }
            }
          },
          "numericValue": {
            "type": "integer"
          }
        }
      }
    }
  }
}

我们创建了一个nestedField,其中字段keystringValue,类型numericValue的{​​{1}}(未分析),keyword(默认标准分析器和类型为子关键字的子字段(如果需要完全匹配),分别为text

第2步:索引文档

integer

请注意如何索引字符串值和数字值。

第3步:根据需要进行查询。

要查询嵌套类型字段,您必须使用nested query

PUT test/_doc/1
{
  "nestedField": [
    {
      "key": "foo",
      "stringValue": "lisa"
    },
    {
      "key": "bar",
      "numericValue": 19
    }
  ]
}

PUT test/_doc/2
{
  "nestedField": [
    {
      "key": "foo",
      "stringValue": "mary"
    },
    {
      "key": "bar",
      "numericValue": 9
    }
  ]
}

上面的查询将仅返回 doc 1 ,因为对于 doc 2 ,即使存在GET test/_search { "query": { "nested": { "path": "nestedField", "query": { "bool": { "filter": [ { "term": { "nestedField.key": "bar" } }, { "range": { "nestedField.numericValue": { "gt": 10 } } } ] } } } } } ,但相关值(key: bar)也存在不大于10。

答案 1 :(得分:0)

从许多Stack-overflow / Github和其他资源中,它确认此功能不适用于文本。

使用它的唯一方法是在索引时具有相应的数字字段:

[
 { "key" : "foo", "value" : "lisa" }, 
 { "key" : "bar", "value" : "19", "numericValue" : 19}
] 



以及基于数值的索引。稍后在从ES中获取时使用它。

1. match key as "bar"
2. range { "numericValue" : {gt:10}}