Как мы можем иметь дело со значениями NULL, которые имеют определенные значения?

вопрос

Я пытаюсь сохранить логическое значение в asticsearch, но оно имеет значение NULL. В этом случае все равно.

Кажется, есть несколько вариантов, но не совсем ясно, что будет лучше.

Мы используем ElasticSearch версии 5.0.2

Опция 1

Тривиальным было бы сохранить его как логическое значение со значениями NULL. Они будут рассматриваться как "отсутствующие" в ES.

PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "my_boolean": { "type": "boolean"}
      }
    }
  }
}

PUT my_index/my_type/1
{"my_boolean": true}

PUT my_index/my_type/2
{"my_boolean": false}

PUT my_index/my_type/3
{"my_boolean": null}

У этого есть несколько проблем, одна из которых является агрегацией. Кажется, нет простого способа получить значения true, false а также NULL в совокупности.

missing функция мне известна, поэтому я знаю, что могу сделать следующее:

GET my_index/_search
{
  "size":0,
  "aggregations": {
    "my_boolean": {
      "terms": {
        "field": "my_boolean"
      }
    },
    "missing_fields": {
          "missing" : {
            "field": "my_boolean"
          }
    }
  }
}

Но это приведет к сегменту с 2 значениями (true/false) и отдельным счетчиком для отсутствующих документов. Похоже, это вызовет проблемы.

Вариант 2

Другой вариант - дать значение NULL, как описано в руководстве. Проблема заключается в том, что значение должно быть правильного типа, и в качестве логического значения ничего, кроме true и false.

Значение null_value должно быть того же типа данных, что и поле. Например, длинное поле не может иметь строку null_value.

Это означает, что мы можем использовать другой тип, который поддерживает более 2 значений, например, целое число, но это было бы в моей голове то же самое, что сказать: давайте сопоставим его как целое число, и определим 1 как true, 2 как false и 3 как null. Это будет работать, но у нас будет неявное отображение, о котором все должны знать. (Все производители / потребители /whatyamahaveits).

Вариант 3

Окончательная версия будет заключаться в том, чтобы попытаться найти выход из этой проблемы.

GET my_index/_search
{
  "size":0,
  "aggregations": {

    "my_boolean": {
      "terms": {
       "script" : {
        "inline": "if(doc['my_boolean'].length === 1) { if(doc['my_boolean'].value === true){ return 1;} else {return 2;} } else { return 3;}"
        }
      }
    }
  }
}

Теперь мы получаем правильные результаты в несколько вменяемых ведрах.

"aggregations": {
"my_boolean": {
  "doc_count_error_upper_bound": 0,
  "sum_other_doc_count": 0,
  "buckets": [
    {
      "key": "1",
      "doc_count": 1
    },
    {
      "key": "2",
      "doc_count": 1
    },
    {
      "key": "3",
      "doc_count": 1
    }
  ]
}
}

Обратите внимание, что у нас все еще есть неявное отображение с ключами здесь, так что, похоже, у него есть некоторые из тех же проблем, что и при сопоставлении с целым числом. Но, тем не менее, ваш тип данных должен быть таким, каким он может быть. Обратите внимание, что у нас не может быть корзины с ключом 'null'. Мы можем назвать их "истинными", "ложными" и "нулевыми" (строками), конечно, но это та же самая ситуация, но скрытая еще больше.

Вопрос

Каков наилучший способ справиться с этой нулевой проблемой? (Или, может быть, мы должны назвать это "tri-state-boolean-problem"?)

Для пояснения: мы опасаемся, что в дальнейшем "нестандартное" значение может вызвать проблемы. Первым, что мы увидели, было объединение, которое мы могли бы исправить с помощью вышеуказанного скриптового решения, но, возможно, позже мы столкнемся с другими проблемами. Поэтому мы ищем лучшую практику сохранения данных такого типа, а не быстрое решение для конкретной проблемы.

2 ответа

Решение

В конце мы пошли для отображения различных состояний в байт.

Отсутствующее значение работает только в том случае, если тип может иметь это значение, поэтому в любом случае нам нужно сопоставление, поэтому мы добавляем дополнительное число во время вставки.

Так что вместо логического с true, false а также null значения или целое число с 1, 2 а также null (с отсутствующим = -1) значения, мы используем байт с 1, 2 а также 3значение (в случайном порядке) true, false а также null,

Вы могли бы использовать missing установка terms агрегация (т.е. не отдельный missing агрегация).

Таким образом, вы могли бы продолжать использовать свое логическое поле и получить три блока с 0, 1 и -1 (для нуля)?

{
  "size":0,
  "aggregations": {
    "my_boolean": {
      "terms": {
        "field": "my_boolean",
        "missing": -1                 <--- add this
      }
    }
  }
}

У него нет недостатка в необходимости изменения типа поля и кодирования его в какой-либо другой тип данных (целое число / строка), а также освобождает вас от использования сценариев, так как это не очень хорошо масштабируется.

Другие вопросы по тегам