Unable to use llist with UDF function

Hi,

I have a llist with following structure: llist

1. list1[abc,pqr,xyz]
2. list2[mnq, rxy, sdf]
3. list3[tyu,dfg,opi]

I have another list say search_list[abc, rtu, dfg]. I have to find the elements in the search_list in llist and return the matched elements list.

My filter function call looks like this

if ( aerospike_llist_filter(&as, &err, NULL, &list1, &llist,
                 "search_filter", (as_list*)&args_list, &result_list) != AEROSPIKE_OK ) {
                fprintf(stderr, " search_keywords :: error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
         }

The LDT used is llist.

as_ldt llist;  as_ldt_init(&llist, "test_list", AS_LDT_LLIST,
    "src/lua/basic_udf.lua");

The args_list["test_list", search_list].

LUA module is as follows:

 function search_filter(rec, bin_name, search_list)
         file = io.open("/tmp/log.lua", "a")
 
         io.write("Inside lua module");
         my_elements = llist_lib.find(rec, bin_name, search_list, nil, nil, nil, nil)
         io.write("I have %d elements in my LLIST", llist_lib.size(rec, bin_name));
         for v in list.iterator(my_elements) do
                 io.write("element = %s", tostring(v))
         end
         io.close(file)
         return my_elements end

After executing the code, I am getting the following error:

 search_keywords :: error(125) AEROSPIKE_ERR_LARGE_ITEM_NOT_FOUND at
 [src/main/aerospike/as_command.c:976]

Moreover, the logs in the lua module are never printed. I am suspecting that the lua module is not getting called. I have registered the module and verified it in aql. Can somebody help me?

Shubhada,

Let me try to understand what you are trying to do. You have llist and you want to scan through that llist and return only the matching object. The match is based on the list pased to the filter function. If true

Load data using python

import aerospike
config = { 'hosts': [("127.0.0.1", 3000)]}
c = aerospike.client(config).connect()
c.apply(("test_D", "", 1), "llist", "add", ["listBin", ["a", "b", "c"]])
c.apply(("test_D", "", 1), "llist", "scan", [])
>>> ['a', 'b', 'c']

What you are trying achieve can be done in two different ways.

  1. Either run UDF on a record with llist bin and do as your Lua file does
  2. Use filter functions to filter out matching result.

For the first the lua file would look like

local llist = require("ldt/lib_llist")   -- Get hold of llist module
function search(rec, binName, search_list)
    info("Inside Lua Module")               -- use aerospike built in logging facility of info/warn/debug. this logs into aerospike.log
    my_elements = llist.scan(rec, binName);
    local result_list = list();
    for v in list.iterator(my_elements) do
        for v1 in list.iterator(search_list) do
            if (tostring(v) == tostring(v1)) then
                 list.append(result_list, v);
            end
        end
   end
   return result_list
end

To Run this you would do

c.apply(("test_D", "", 1), "heh", "search", ["listBin", ["b","c"]])
>>> ['b', 'c']

Second case you can run LDT scan and apply filter function. This is what your C function does.

In that case you filter function is wrong. It should look like

local myfilter_module ={}
function myfilter_module.search_filter(object, search_list)
    info("Inside Lua Module");
    for v in list.iterator(search_list) do
        if (tostring(v) == tostring(object)) then  -- object ['key'] if the key is explicit
            return object;
        end
    end
end
return myfilter_module

Parameter passed to filter function are a single item in the llist along with the filter args. Refer to https://www.aerospike.com/docs/guide/ldt_advanced.html

Note that aerospike had info/warn/debug logging function available which can be used. Note that you cannot access llist from inside the filter function.

You would run it like

c.apply(("test_D", "", 1), "llist", "filter", ["listBin", None, "f", "search_filter", ["b","c"]])
>>> ['b', 'c']

HTH

– Raj

Thanks Raj. I have tried the solution(approach 1) and it works!!

1 Like