Aerospike:即使UDF返回流而没有任何筛选,lua udf始终返回空结果

不明白为什么aggregateQuery总是返回一个空结果。在aql中尝试测试,同样的问题:集合中没有行。

所有索引都在那里。

aql> show indexes
+---------------+-------------+-----------+------------+-------+------------------------------+-------------+------------+-----------+
| ns            | bin         | indextype | set        | state | indexname                    | path        | sync_state | type      |
+---------------+-------------+-----------+------------+-------+------------------------------+-------------+------------+-----------+
| "test"        | "name"      | "NONE"    | "profiles" | "RW"  | "inx_test_name"              | "name"      | "synced"   | "STRING"  |
| "test"        | "age"       | "NONE"    | "profiles" | "RW"  | "inx_test_age"               | "age"       | "synced"   | "NUMERIC" |

aql> select * from test.profiles
+---------+-----+
| name    | age |
+---------+-----+
| "Sally" | 19  |
| 20      |     |
| 22      |     |
| 28      |     |
| "Ann"   | 22  |
| "Bob"   | 22  |
| "Tammy" | 22  |
| "Ricky" | 20  |
| 22      |     |
| 19      |     |
+---------+-----+
10 rows in set (0.026 secs)

aql>  AGGREGATE mystream.avg_age() ON test.profiles WHERE age BETWEEN 20 and 29
0 rows in set (0.004 secs)
点赞
用户6171361
用户6171361

似乎你正在尝试这里的示例(http://www.aerospike.com/docs/tools/aql/querying_records.html#aggregating-on-query-or-scan-results)。

关于udf脚本有两个问题。我粘贴lua脚本的代码:

function avg_age(stream)

  local function female(rec)
    return rec.gender == "F"
  end

  local function name_age(rec)
    return map{ name=rec.name, age=rec.age }
  end

  local function eldest(p1, p2)
    if p1.age > p2.age then
      return p1
    else
      return p2
    end
  end

  return stream : filter(female) : map(name_age) : reduce(eldest)
end

首先,你的集合中没有名为“gender”的bin,所以在聚合查询后得到0行。

其次,这个脚本并不完全做到了函数名称“avg_age”的意思,它只返回了带有名称和年龄的最年长的记录。

我将我的代码粘贴在下面,它只是替换了reduce函数,并警惕map和filter函数以满足要求。您可以跳过筛选过程。

function avg_age(stream)
  count = 0
  sum = 0

  local function female(rec)
    return true
  end

  local function name_age(rec)
    return rec.age
  end

  local function avg(p1, p2)
    count = count + 1
    sum = sum + p2
    return sum / count
  end

  return stream : filter(female) : map(name_age) : reduce(avg)
end

输出看起来像下面:

AGGREGATE mystream.avg_age() ON test.avgage WHERE age BETWEEN 20 and 29
+---------+
| avg_age |
+---------+
| 22      |
+---------+
1 row in set (0.001 secs)
2016-05-08 00:31:05