ПРИМЕЧАНИЕ: вы, вероятно, не должны хранить его как массив, так как элементы массива хранятся как вложенные объекты.Кроме того, индексированные массивы не соответствуют первоначальному порядку.Итак, вы должны сохранить его как 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
"""
},