为Aerospike编写聚合(groupBy, orderBy) Lua脚本的指导。

我有一个 Lua 脚本,它以 'sensorType' 为依据分组数据,并在每个 'sensorType' 组中打印 'clientId'。

function orderby(touples)
  local function mapper(rec)
  local element = map()
    element["clientId"] = rec["clientId"];
    element["sensorType"] = rec["sensorType"]
  return element
end

local function accumulate(currentList, nextElement)
   local sensorType = nextElement["sensorType"]
   local clientId = nextElement["clientId"]
     if currentList[sensorType] == nil then
         currentList[sensorType] = list()
     end

    list.append(currentList[sensorType],clientId)

  return currentList
end
local function mymerge(a, b)
   return list.merge(a, b)
end
local function reducer(this, that)
   return map.merge(this, that, mymerge)
end
return touples:map(mapper):aggregate(map{}, accumulate):reduce(reducer)
end

我还想按 'groupBy sensorType, clientId' 进行分组。请帮我准备一个可以接受任意组别子句列数并进行分组的脚本。

目前我的结果是-

{ BEACON: [ 'client2', 'client2', 'client2', 'client2', 'client2', 'client2' ],
  SSID:
   [ '100',
     '100',
     '100',
     '100',
     '100',
     '100',
     '100',
     '102',
     '100',
     '100',
     '101',
     '100' ] }

我想要的结果是这个格式-

{ BEACON: [ 'client2' ],
  SSID:
   [ '100',
     '102',
     '101', ] }
点赞
用户3685847
用户3685847

在您的函数 accumulate 中,clientId 无条件添加到 currentList 中。如果您不想在 currentList 中有冗余数据,则需要检查 clientId 是否属于 currentList

如果您使用的是列表而不是集合,则这有点棘手;您需要逐个测试每个元素:

local t = currentList[sensorType]
local alreadyInList = false
for i = 1, #t do
    if t[i] == clientId then
        alreadyInList = true
    end
end
if not alreadyInList then
    list.append(t, clientId)
end

这会比较慢——随着 currentList[sensorType] 的增长,测试其是否已经包含您正在尝试添加的元素也将需要更长的时间。在许多情况下,这没有多大区别,但是使用 set 而不是列表将更快(也更容易)。在 Lua 中,集合非常容易,因为任何东西都可以作为 Lua 表的键,甚至是另一个表。这是您如何使用表作为集合而不是列表:

--将一个空表初始化为集合
if currentSet[sensorType] == nil then
    currentSet[sensorType] = {}
end
--将数据添加到集合 `currentList[sensorType]` 中
currentSet[sensorType][clientId] = true

--在适当的时候,将集合重新转换为列表
convertedList = {}
i = 0
for key in pairs(currentSet[sensorType]) do
    i = i + 1
    convertedList[i] = key
end

转换之前,currentSet 如下所示:

{ [sensorType] =
    { ["100"] = true
    , ["101"] = true
    , ["102"] = true
    }
}

转换后,convertedList 如下所示:

{ "100", "102", "101" }

(请注意,convertedList 可以以任何顺序出现,因为 Lua 表内键的顺序是未定义的。)

2015-10-22 20:22:28