两个或多个排序集合的交集

6

我有两个已排序的集合,想要进行交集操作,即(年龄在25到35岁之间)并且(薪资在250到350之间)

除了以下方法,是否存在更高效的方式:

ZUNIONSTORE t_age 1 age WEIGHTS 1
ZREMRANGEBYSCORE t_age -inf (25
ZREMRANGEBYSCORE t_age (35 +inf
ZINTERSTORE result 2 salary t_age WEIGHTS 1 0
ZRANGEBYSCORE result 250 350

1
你的意思是 ZINTERSTORE result 2 salary t_age WEIGHTS 1 0 中的零吗? - thepirat000
1
一个假设的命令ZRANGEBYSCORESTORE,它可以存储结果,有助于聚合数据。此外,ZREMRANGEBYSCORE的独占版本... - thepirat000
请查看这个链接 - thepirat000
2个回答

4
你应该先通过 ZCARD 检查哪个 ZSET 元素较少,然后克隆并修剪较短的那个。
其次,你留下了两个剩余物。你可以重复使用同一个辅助 ZSET 来更快地清理。
我还想建议使用 DUMPRESTORE 进行克隆,但对于排序集合的情况,ZUNIONSTORE 实际上要快得多。 以下是一个1M元素集合的时间计时:
1) 1) (integer) 14
   2) (integer) 1444165498
   3) (integer) 936762
   4) Complexity info: N:1000000,M:1000000
   5) 1) "ZUNIONSTORE"
      2) "temp3"
      3) "1"
      4) "temp1"
      5) "WEIGHTS"
      6) "1"
2) 1) (integer) 13
   2) (integer) 1444165421
   3) (integer) 3166360
   4)
   5) 1) "evalsha"
      2) "48286113cfe4b389d516e98646e5f4e086decc34"
      3) "2"
      4) "temp1"
      5) "temp2"
      6) "0"

1
这实际上是我心中最初的答案。虽然基数大小的评论很重要,但考虑到年龄/薪资背景,我猜想两个集合具有相同的成员。但是,经过基准测试后,我想到了另一种方法,其性能提高了约35倍。我打算在即将举行的Redis开发者日活动中分享这些内容...敬请关注 :) - Itamar Haber
@ItamarHaber 这是否涉及到Lua脚本编写? - mpapec
@ItamarHaber 只是猜测,两个ZRANGEBYSCORE,两个多重SADD和一个SINTERSTORE?(我不会在会议上的:)) - mpapec
我们计划撰写有关RDD的所有内容,以便社区受益,即使特定成员无法参加也可以了解。我的方法需要不同的数据结构(目前我正在使用哈希表进行查询)。顺便问一下,你的集合基数是多少?我在10万个成员上进行了“基准测试”,但实际数字总是更有帮助的。 - Itamar Haber
@ItamarHaber 我有大约20k的成员,所以它们可能不会对Redis造成问题。 - mpapec

4
我有一个想法,可以使用不同的数据结构,即四叉树,更有效地实现相同类型的查询。您可以在此处查看我的小型POC(Redis Quadtree in Hash),使用“面向对象”的Lua编写: https://gist.github.com/itamarhaber/c1ffda42d86b314ea701 注意:您应该知道,在Redis开发者日之前、期间和之后,这引发了极为有趣的讨论。中间结果是新的indexing page,但在不久的将来,Redis可能会添加一个更高级的API,使n维索引变得轻松易用。

1
太好了,感谢您帮助将此功能加入Redis核心。 - mpapec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接