【问题标题】:Aerospike: lua udf always returns an empty result even if udf return stream without any filtering, etcAerospike:lua udf 总是返回一个空结果,即使 udf 返回流没有任何过滤等
【发布时间】:2016-03-30 15:27:08
【问题描述】:

无法理解为什么 aggregateQuery 总是返回空结果。尝试在aql中测试,同样的问题:集合中的0行。

索引都在那里。

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)

【问题讨论】:

  • 你能在不调用udf的情况下通过aql共享lua文件和查询结果吗?
  • 你有建立在 age bin 上的索引吗?当你只是SELECT * FROM test.profiles WHERE age BETWEEN 20 AND 29 时会发生什么?此外,您需要展示您的 Lua 模块才能弄清楚这一点。

标签: lua udf aerospike


【解决方案1】:

您似乎正在尝试示例here
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

首先,您的集合中没有名为“性别”的 bin,因此在 aggregateQuery 之后有 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 2012-09-09
    • 2011-05-09
    • 2021-11-21
    • 2019-03-28
    相关资源
    最近更新 更多