Redis / Mongo排序列表复杂性

时间:2015-01-11 09:24:39

标签: mongodb sorting redis sortedlist sortedset

我知道这不是一个公平的比较,但我的问题在理论上是关于操作的复杂性。

Redis(排序集) -

  • ZADD - 时间复杂度:O(log(N))其中N是元素的数量 在排序集中。
  • ZRANGE - 时间复杂度:O(log(N)+ M)与N. 是有序集合中的元素数量,M是数量 元素返回。

排序数组上的Mongo等价物是什么:

{
   sorted_list : [{name : <string>,score : <Number>}]
}

collection.update(
   { _id: 1 },
   {
     $push: {
       sorted_list: {
         $each: [ { name: 3, score: 8 }, { name: 4, score: 7 }, { name: 5, score: 6 } ],
         $sort: { score: 1 }
       }
     }
   }
)

collection.find( { _id: 1}, { sorted_list: { $slice: [ 20, 10 ] } } )

updatefind操作的复杂性是什么?

此外,我的目标是找到一个解决方案,其中“读取”操作(从排序列表中的索引拉出)将是最佳的 - O(1)。并且仍然有O(log(N))插入。这应该是可行的利用内存(具有排序集的数组副本)。 是否有实施它的平台?

1 个答案:

答案 0 :(得分:2)

我已经为mongodb中的项目实现了zadd和zrange,尽管我没有将已排序的set元素存储在嵌入式数组中。

我对嵌入式阵列的问题在于没有简单的方法来确保元素是唯一的。在你的情况下,有人可以zadd具有相同名称但具有不同分数的另一个元素。在这种情况下,redis只更新元素的分数,并且不添加新元素。

因此,我没有使用嵌入式数组,而是将每个有序集元素设置为以下形式的新文档。

{
 _key: "sortedSetKey",
 value: "value1",
 score: 12
},
{
 _key: "sortedSetKey",
 value: "value2"
 score: 3
}

{_key: 1, score: -1}{_key: 1, value: -1}的集合中有2个复合索引。

完成所有这些后,将新元素添加到已排序的集合中:

db.objects.update({_key: key, value: value}, {$set: {score: parseInt(score, 10)}}, {upsert: true});

这将是O(log(n)),因为(key,value)上有一个索引。

获得范围有点复杂:

db.objects.find({_key: key}, {fields: {_id: 0, value: 1})
    .limit(stop - start + 1)
    .skip(start)
    .sort({score: sort})

同样,它使用键索引查找属于有序集的所有元素,然后对得分字段进行排序,以便使用复合索引。 limit和skip用于获取已排序集的一部分。显然这不是O(1)。如果在较大的有序集中传入较高的skip值,它将扫描许多文档。

希望能给出一些想法。

您可以查看完整的来源here