luahigh-loadtarantoolnosql

Tarantool: limit/offset in index.indexName:pairs call


I need to fetch some records from space users. This space has a secondary index category_status_rating. I need select users with category=1, status=1, rating<=123456789:

for _, user in box.space.users.index.category_status_rating:pairs({ 1, 1, 123456789 }, { limit = 20, offset = 5, iterator = box.index.LE }) do
    if user[categoryIdx] ~= 1 or user[statusIdx] ~= 1 then break end
    table.insert(users, user)
end

As I know, iteration with indexName:pairs does not support limit and I can just user my own counter. But what about offset? Can I use this param and start from "page" I need? Or will I iterate without any offset and pass useless records (about 100000) and start to table.insert(users, user) when my "page" starts? Thanks!


Solution

  • Instead of using offset, you can save your position (that will be last checked tuple) if you really need it. e.g:

    local last = 123456789
    for i = 1, 2 do
        local count = 0
        for _, user in box.space.users.index.category_status_rating:pairs({1, 1, last}, { iterator = box.index.LE }) do
            if user[categoryIdx] ~= 1 or user[statusIdx] ~= 1 or count > 20 then
                break
            end
            table.insert(users, user)
            last = user[LAST_INDEX_FIELD]
            count = count + 1
        end
        -- process your tuples
    end
    

    or, using luafun (where drop_n is analog of limit, and saving into last is analog of offset):

    local last = 123456789
    for i = 1, 2 do
        local users = box.space.users.index.category_status_rating:pairs({1, 1, last}, { iterator = box.index.LE }):take_n(20):map(function(user)
            last = user[LAST_INDEX_FIELD]
            return user
        end):totable()
        -- process your tuples
    end
    

    Documentation on LuaFun, which is embedded into Tarantool.