lua - 指导我为 Aerospike 编写聚合(groupBy、orderBy)Lua 脚本

标签 lua aggregate-functions aerospike

我有一个以下 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

我还想要带有 clientId 的 groupBy,例如“groupBysensorType, clientId”。请帮助我准备一个脚本,该脚本可以接受任意数量的 groupBy 子句列并用它进行分组。

目前我的结果是-

{ 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', ] } 

最佳答案

在您的函数 accumulate 中,clientId 无条件添加到 currentList 中。如果您不希望 currentList 中存在冗余数据,则需要检查 currentListclientId 的成员资格。

如果您使用列表而不是集合,这会有点棘手;您必须单独测试每个元素:

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] 的增长,需要更长的时间来测试它是否已包含您要添加的元素。在许多情况下,这不会产生太大的区别,但使用一组元素而不是列表会更快(也更容易)。 Lua 中的集合非常简单,因为任何东西都可以成为 Lua 表的键,甚至是另一个表。以下是如何将表格用作集合而不是列表:

-- initialize a set as an empty table
if currentSet[sensorType] == nil then
    currentSet[sensorType] = {}
end
-- add the data to the set `currentList[sensorType]`
currentSet[sensorType][clientId] = true

-- when appropriate, convert the set back into a list
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 表中键的顺序未定义。)

关于lua - 指导我为 Aerospike 编写聚合(groupBy、orderBy)Lua 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33219056/

相关文章:

cassandra - 在开源 Cloud Foundry 中实现 Cassandra 和 Aerospike 的 Service Broker API

Aerospike - 存储*少量*大值(value)

replication - 具有不同复制因子的 Aerospike 集群

logging - 记录上游请求 Nginx 反向代理

sql - 跨连接表获取多个计数

sql - 如何计算具有 HAVING 条件的 MySQL 条目

postgresql - SqlAlchemy:多个列的不同计数

lua - 在Torch中将表写入文件

compiler-construction - 静态类型的 Lua

plugins - 为魔兽世界开发插件 - 开始?