我知道这不是一个公平的比较,但我的问题在理论上是关于操作的复杂性。
Redis(排序集) -
排序数组上的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 ] } } )
update
和find
操作的复杂性是什么?
此外,我的目标是找到一个解决方案,其中“读取”操作(从排序列表中的索引拉出)将是最佳的 - O(1)。并且仍然有O(log(N))插入。这应该是可行的利用内存(具有排序集的数组副本)。 是否有实施它的平台?
答案 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