Aerospike: 如何批量加载整数列表到一个Bin中?

我正在尝试使用[Aerospike批量加载程序](https://github.com/aerospike/aerospike-loader“ Aerospike批量加载程序”)从制表符分隔的文件中向集群种植数据。

源数据如下:

set key segments
segment 123 10,20,30,40,50
segment 234 40,50,60,70

第三列'segments'包含一个逗号分隔的整数列表。

我创建了一个JSON模板:

{
  "version" : "1.0",
  "input_type" : "csv",
  "csv_style": { "delimiter": " " , "n_columns_datafile": 3, "ignore_first_line": true}

  "key": {"column_name":"key", "type": "integer"},

  "set": { "column_name":"set" , "type": "string"},

  "binlist": [
    {"name": "segments",
      "value": {"column_name": "segments", "type": "list"}
    }
  ]
}

并运行加载程序:

java -cp aerospike-load-1.1-jar-with-dependencies.jar com.aerospike.load.AerospikeLoad -c template.json data.tsv

当我在aql中查询记录时,它们似乎是字符串列表:

aql> select * from test
+--------------------------------+
| segments                       |
+--------------------------------+
| ["10", "20", "30", "40", "50"] |
| ["40", "50", "60", "70"]       |
+--------------------------------+

我试图存储的数据是整数列表。是否有一种轻松的方法将存储在此章节中的对象转换为整数列表(可能是Lua UDF)或者可能有一种方法可以进行批量加载程序模板的调整?

##更新: 我试图创建一个Lua UDF以将列表从字符串转换为整数:

function convert_segment_list_to_integers(rec)
    for i=1, table.maxn(rec['segments']) do
        rec['segments'][i] = math.floor(tonumber(rec['segments'][i]))
    end
    aerospike:update(rec)
end

…注册了它:

aql> register module 'convert_segment_list_to_integers.lua'

…然后尝试对我的集合执行:

aql> execute convert_segment_list_to_integers.convert_segment_list_to_integers() on test.segment

我启用了更详细的日志记录并注意到UDF出现错误。显然,它期望传递'table'而传递'userdata':

Dec 04 2015 23:23:34 GMT: DEBUG (udf): (udf_rw.c:send_result:527) FAILURE when calling convert_segment_list_to_integers convert_segment_list_to_integers ...rospike/usr/udf/lua/convert_segment_list_to_integers.lua:2: bad argument #1 to 'maxn' (table expected, got userdata)
Dec 04 2015 23:23:34 GMT: DEBUG (udf): (udf_rw.c:send_udf_failure:407) Non-special LDT or General UDF Error(...rospike/usr/udf/lua/convert_segment_list_to_integers.lua:2: bad argument #1 to 'maxn' (table expected, got userdata))

似乎“maxn”不适用于“userdata”对象。

您是否可以看到需要完成的内容以解决此问题?

点赞
用户3512898
用户3512898

要将具有字符串值的列表转换为整数值列表,您可以运行以下记录UDF

function convert_segment_list_to_integers(rec)
        local list_with_ints = list()
        for value in list.iterator(rec ['segments']) do
                local int_value = math.floor(tonumber(value))
                list.append(list_with_ints, int_value)
        end
        rec['segments'] = list_with_ints
        aerospike:update(rec)
end

在编辑现有的lua模块时,请确保重新运行register module'convert_segment_list_to_integers.lua'

这个问题的原因在于aerospike-loader工具:正如您在以下java代码中看到的那样,它总是假定/强制为字符串:

case LIST:
    /*
     *假设
     * 1.项目由冒号“,”分隔
     * 2.项目值将是一个字符串
     * 3.列表将用双引号括起来
     *
     *不支持嵌套映射或嵌套列表
     *
     **/
    List<String> list = new ArrayList<String>();
    String[] listValues = binRawText.split(Constants.LIST_DELEMITER,-1);
    if(listValues.length > 0){
        for(String value:listValues) {
            list.add(value.trim());
        }
        Bin.作为列表(binColumn.getBinNameHeader(),列表);
    } else {
        bin = 0;
        log.error("错误:无法解析为列表:"+binRawText);
    }
    破裂;

Github上的源:http://git.io/vRAQW

如果您喜欢,可以修改此代码并重新编译以始终假定整数列表值。将第266行和第270行更改为类似于以下内容(未经测试):

List<Integer> list = new ArrayList<Integer>();
list.add(Integer.parseInt(value.trim());
2015-12-09 23:23:02