【问题标题】:Storing JSON array string elasticsearch Bug存储 JSON 数组字符串 elasticsearch 错误
【发布时间】:2017-10-14 21:09:15
【问题描述】:

我观察到 Elasticsearch 5.2 出现了一些奇怪的行为,并且无法调试 - 因为没有抛出错误,我也无法在线找到类似的问题/文档。

我将 JSON 数组存储为 elasticsearch 中的“字符串”(使用 python 的 json.dumps())——长话短说,我必须这样做。但是,当我执行 DSL 查询时,只显示包含 1 个对象的 JSON 数组(存储为单个字符串)。如果大于 1,那么它只返回一个空的桶 0 个对象。我将它们存储在一个名为“元数据”的字段中。

我很困惑为什么只显示数据的一个子集,而忽略其他数据(在 json 数组中有超过 1 个对象)。数据被编码为字符串。我知道事实上存储在索引中的数据。我可以在 kibana“发现”中看到它——因为我可以看到带有多个对象的大型 JSON 字符串。

示例 1(带有 1 个对象的 JSON 字符串):

[{“分数”:0.8829717636108398,“高度”:0.875460147857666,“宽度”: 0.3455989360809326,“y”:0.08105117082595825,“x”:0.5616265535354614,“note”:“box1”}]

示例 2:

[{“分数”:0.8829717636108398,“高度”:0.875460147857666,“宽度”: 0.3455989360809326,“y”:0.08105117082595825,“x”:0.5616265535354614,“note”:“box1”},{“score”:0.6821991136108398,“height”: 0.875460147857666,“宽度”:0.3455989360809326,“y”:0.08105117082595825,“x”:0.5616265535354614,“注意”:“box2”}]

这是我的查询:

{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "analyze_wildcard": true,
            "query": "*"
          }
        },
        {
          "range": {
            "created_at": {
              "gte": 1508012482796,
              "lte": 1508014282797,
              "format": "epoch_millis"
            }
          }
        }
      ],
      "must_not": []
    }
  },
  "size": 0,
  "_source": {
    "excludes": []
  },
  "aggs": {
    "5": {
      "terms": {
        "field": "metadata.keyword",
        "size": 31,
        "order": {
          "_count": "desc"
        }
      }
    }
  }
}

此查询仅返回带有 1 个对象的字符串。见下文:

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 4214,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "5": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 35,
      "buckets": [
        {
          "key": "[]",
          "doc_count": 102
        },
        {
          "key": "{}",
          "doc_count": 8
        },
        {
          "key": "[{\"score\": 0.9015679955482483, \"height\": 0.8632315695285797, \"width\": 0.343660831451416, \"y\": 0.08102986216545105, \"x\": 0.5559845566749573, \"note\": \"box11\"}]",
          "doc_count": 6
        },
        {
          "key": "[{\"score\": 0.6365205645561218, \"height\": 0.9410756528377533, \"width\": 0.97696852684021, \"y\": 0.04701271653175354, \"x\": 0.013666868209838867, \"note\": \"box17\"}]",
          "doc_count": 4
        },
...
}

正如观察到的,只有带有 1 个对象(即 [{..}])的 JSON 字符串的数据被返回/可见。它完全忽略了具有多个对象的字符串(即 [{...},{...}])。

更多说明:

  • 它使用默认映射
  • 我可以得到 JSON 字符串(不管对象的数量) 当通过文档 id 查询,或通过精确字段值使用“匹配”时)

【问题讨论】:

  • 我想问几个问题。首先,能否请您提供您的映射?其次,您是否能够通过文档 ID 检索此类 JSON 数组?第三,您是否想将此类文档(如示例 2)作为您提供的聚合中的存储桶之一?谢谢。
  • 我认为关键字字段也应用了"ignore_above": 256,因此JSON数组中具有两个或多个对象的字段没有被索引。
  • 1) 我使用的是默认映射。因此,它有两个字段“metadata”(已分析)和“metadata.keyword”(未分析,但可聚合)。 2) 是的,我看到以字符串格式存储的数据。就像上面提供的示例一样。只有当我执行聚合查询时它才会中断。 3)没错,bucket是完全空的(我试过其他查询,buckets是“[]”)。
  • @val,感谢您的反馈,但我不认为我可以在文档中看到它的索引。我只是在运行 DSL 查询时没有得到数据
  • 您在文档中看到的是来源。被索引的内容是不同的。运行curl -XGET localhost:9200/your_index 会得到什么?

标签: elasticsearch kibana elasticsearch-dsl


【解决方案1】:

如果您使用的是默认映射,这很可能是因为您的关键字映射有一个ignore_above: 256 设置并且看起来像这样:

{
  "mappings": {
    "my_type": {
      "properties": {
        "metadata": {
          "type":  "keyword",
          "ignore_above": 256
        }
      }
    }
  }
}

您可以增加该限制,以便为超过 256 个字符的 JSON 字符串编制索引。

【讨论】:

    猜你喜欢
    • 2017-06-14
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    相关资源
    最近更新 更多