Хранение строки массива JSON, ошибка elasticsearch

Я наблюдаю какое-то странное поведение Elasticsearch 5.2, и его невозможно отладить, поскольку ошибок не возникает, и я не могу найти аналогичные проблемы/документацию в Интернете.

Я сохраняю массив JSON как «строку» в elasticsearch (используя json.dumps() python) — короче говоря, я должен сделать это так. Однако, когда я выполняю запрос DSL, отображаются только массивы JSON (хранящиеся в виде единственной строки), содержащие 1 объект. Если больше 1, то он просто возвращает пустое ведро 0 объектов. Я храню их в поле под названием «метаданные».

Я очень смущен, почему отображается только подмножество данных, а другие данные (с более чем 1 объектом в массиве json) игнорируются. Данные кодируются как строка. Я точно знаю, что данные, хранящиеся в index. Я вижу это в «обнаружении» кибаны — я вижу большие строки JSON с несколькими объектами.

Пример 1 (строка JSON с 1 объектом):

[{"score": 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,5616165535355555555111111111111146595825, «x»: 0,5616655353535555555555555555551,1,13, ": 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
        },
...
}

Как видно, возвращаются/видимы только данные со строками JSON с 1 объектом (т.е. [{..}]). Он полностью игнорирует строки с несколькими объектами (например, [{...}, {...}]).

Дополнительные разъяснения:

  • Он использует сопоставления по умолчанию
  • Я могу получить строку JSON (независимо от количества объектов) при запросе по идентификатору документа или с использованием «соответствия» по точным значениям поля)

person cynical biscuit    schedule 14.10.2017    source источник
comment
Я хотел бы задать пару вопросов. Во-первых, не могли бы вы предоставить свое отображение? Во-вторых, можете ли вы получить такие массивы JSON по идентификатору документа? В-третьих, правильно ли я понимаю, что вы хотите получить такие документы (например, пример 2) как один из сегментов в предоставленной вами совокупности? Спасибо.   -  person Nikolay Vasiliev    schedule 15.10.2017
comment
Я думаю, что к полю ключевого слова также применяется "ignore_above": 256, поэтому поля с двумя или более объектами в массиве JSON не индексируются.   -  person Val    schedule 15.10.2017
comment
1) Я использую сопоставление по умолчанию. Следовательно, он имеет два поля metadata (анализируемые) и metadata.keyword (не анализируемые, но агрегируемые). 2) Да, я вижу, что данные хранятся в строковом формате. Как в приведенном выше примере. Только когда я делаю агрегированные запросы, он ломается. 3) Точно, ведро совсем пустое (пробовал другие запросы, ведра []).   -  person cynical biscuit    schedule 15.10.2017
comment
@val, спасибо за отзыв, но я не думаю, что это тот случай, когда я вижу, что он проиндексирован в документе. Я просто не получаю данные, когда запускаю DSL-запрос   -  person cynical biscuit    schedule 15.10.2017
comment
То, что вы видите в документе, является источником. То, что индексируется, отличается. Что вы получаете при запуске curl -XGET localhost:9200/your_index ?   -  person Val    schedule 15.10.2017
comment
@val, ты прав. Я вижу ignore_above 256. Это проблема? Странно, что он точно индексирует массив JSON, чтобы он заканчивался объектами 1 и 0, не испортив отступ или стиль. Возможно, для 1 объекта это в пределах 256 байт. Я проверю это. Спасибо большое   -  person cynical biscuit    schedule 15.10.2017
comment
Да, один объект меньше 256 символов, а два или более больше   -  person Val    schedule 15.10.2017


Ответы (1)


Если вы используете сопоставление по умолчанию, это, скорее всего, связано с тем, что сопоставление ключевых слов имеет ignore_above: 256 настройки и выглядит следующим образом:

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

Вы можете увеличить это ограничение, чтобы индексировать строки JSON длиннее 256 символов.

person Val    schedule 15.10.2017