Как сохранить логический массив и выполнить операции XOR в Elasticsearch? - PullRequest
2 голосов
/ 28 марта 2019

Я хотел бы начать использовать ElasticSearch, чтобы сохранить некоторые предварительно вычисленные результаты, которые мне нужно будет сопоставить впоследствии. Этот результат представляет собой 200-битный массив, связанный с идентификатором.

Чтобы выполнить сопоставление, мне нужно будет выполнить операцию XOR между входом поиска и сохраненными битарными массивами для моих существующих элементов и отсортировать по количеству оставшихся битов (количество элементов).

Можно ли вообще это сделать, используя Painless или другие скриптовые стратегии? И если это так, какой тип отображения лучше всего использовать для хранения этого битового массива?

Спасибо!

1 Ответ

1 голос
/ 28 марта 2019

ПРИМЕЧАНИЕ: вы, вероятно, не должны хранить его как массив, так как элементы массива хранятся как вложенные объекты.Кроме того, индексированные массивы не соответствуют первоначальному порядку.Итак, вы должны сохранить его как keyword.

Экспериментируя немного, и я думаю, что я нашел что-то, что будет работать (вам придется экспериментировать с вашими большими числами, чтобы проверить).

Во-первых: индексируйте его как тип keyword, вам нужно убедиться, что ваша длина keyword указывает соответствующую максимальную длину.

"binary_string" :
   "type" : "keyword",
   "ignore_above" : 256 // <-- Whatever your max binary string length will be
}

Второе: тогда вы можете sort запрос, основанный на скриптовом поле, используя безболезненно

GET binary_test/_search
{
  "sort": [
    {
      "_script" : {
            "type" : "string",
            "script" : {
                "lang": "painless",
                "source": """
                def val1 = new BigInteger(doc['binary_string'].value, 2);
                val1.xor(new BigInteger("000000000", 2)).toString(2) // whatever your binary string is that you are comparing to
                """
            },
            "order" : "asc"
        }
    }
  ]
}

Соображения:

  • Причина сортировкистроковое значение xor означает, что числа хранятся как float, и возможная потеря точности может стоить вам.
  • Построение двух значений BigInteger и использование BigInteger#xor могут быть медленнее, чем простоперебирая две строки и создавая новую самостоятельно, я бы поэкспериментировал с этим, если вы заботитесь о производительности.

Если вас не интересует фактическое число бит, вы можете сделать следующеепросто будьте осторожны с несоответствием длины битрейра (если это возможно с вашим вводом)

"_script" : {
   "type" : "number",
       "script" : {
                "lang": "painless",
                "source": """
                def val1 = doc['binary_string'].value;
                def val2 = "000000000"; // <-- the string you care about
                def count = 0;
                for(int i; i < val2.length; i++) {
                  if (val1.charAt(i) != val2.charAt(i)) {
                    count++;
                  }
                }
                count
                """
            },

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...