【发布时间】:2019-07-25 23:35:51
【问题描述】:
我正在尝试在 elasticsearch 6.7 中有效地存储和检索浮点数组。 Numeroc doc 值已排序,这意味着我不能直接使用它们。
一开始我是用source这个字段的值,但是在大型查询上性能不是很好。
我尝试将浮点数组编码为二进制并在我的脚本中对其进行解码。不幸的是,我坚持将byte[4] 数组转换为painless 中的float。
在 Java 中是这样的
Float.intBitsToFloat((vector_bytes[3] << 24) | ((vector_bytes[2] & 0xff) << 16) | ((vector_bytes[1] & 0xff) << 8) | (vector_bytes[0] & 0xff));
但是用& 0xff 丢弃标志会毫无痛苦地抛出"Illegal tree structure."。
知道如何做到这一点吗?
小例子:
设置索引
# Minimal example binary array
# Create the index
PUT binary_array
{
"mappings" : {
"_doc" : {
"properties" : {
"vector_bin": { "type" : "binary", "doc_values": true },
"vector": { "type" : "float" }
}
}
}
}
# Put two documents
PUT binary_array/_doc/1
{
"vector": [1.0, 1.1, 1.2],
"vector_bin": "AACAP83MjD+amZk/"
}
PUT binary_array/_doc/2
{
"vector": [3.0, 2.1, 1.2],
"vector_bin": "AABAQGZmBkCamZk/"
}
样本搜索将二进制数组转换回数组
GET binary_array/_search
{
"script_fields": {
"vector_parsed": {
"script": {
"source": """
def vector_bytes = doc["vector_bin"].value.bytes;
def vector = new float[vector_bytes.length/4];
for (int i = 0; i < vector.length; ++i) {
def n = i*4;
// This would be the Java way, discarding the sign of bytes 0-2, but is raises a "Illegal tree structure." in painless
//def intBits = (vector_bytes[n+3] << 24) | ((vector_bytes[n+2] & 0xff) << 16) | ((vector_bytes[n+1] & 0xff) << 8) | (vector_bytes[n] & 0xff);
// This runs but gives incorrect results
def intBits = (vector_bytes[n+3] << 24) | ((vector_bytes[n+2] ) << 16) | ((vector_bytes[n+1] ) << 8) | (vector_bytes[n] );
vector[i] = Float.intBitsToFloat( intBits );
}
return vector;
"""
}
},
"vector_src": {
"script": """params._source["vector"]"""
}
}
}
【问题讨论】:
标签: elasticsearch elasticsearch-6 elasticsearch-painless