mongodb $ size如何运作?

时间:2015-08-19 22:45:06

标签: mongodb

假设我有一个集合"帖子",并且帖子可以有评论,这些评论作为数组存储在帖子文档中,如下所示:

λ> :k Compose Const
Compose Const :: (k -> *) -> k -> k1 -> *

如果我想计算特定帖子的评论数量,我可以{ ... comments : [ ... ] ... } 。但是,看一下bson二进制格式,看起来它实际上并不存储数组的大小,它只是一个带有键0,1,2的文档...

如果是这种情况,是否必须遍历所有评论来计算它们?这似乎效率低下,特别是如果你有很多帖子说超过1000条评论。

有一个明显的解决方法。只需将计数存储在文档中。

{ $size : "$comments" }

我很好奇mongo是否在幕后做了一件我不应该担心的问题。

感谢。

1 个答案:

答案 0 :(得分:1)

你老老实实地说过这个:

  

“它只是一个带有键的文档,0,1,2 ......”

因此,“last”键索引是数组大小的n-1。因此,如果最后一个索引是“49”,则数组的大小为“50”。

还要记住,BSON本身总是被解析为本机表示。对于服务器,这是一个表示数组的结构,是的,它也包含length属性。

因此它不需要“迭代”和计数,它只是从已经存储的内容中读取信息。

实际上,具体来说它完全是this

Value ExpressionSize::evaluateInternal(Variables* vars) const {
    Value array = vpOperand[0]->evaluateInternal(vars);

    uassert(17124,
            str::stream() << "The argument to $size must be an Array, but was of type: "
                          << typeName(array.getType()),
            array.getType() == Array);
    return Value::createIntOrLong(array.getArray().size());
}

REGISTER_EXPRESSION(size, ExpressionSize::parse);
const char* ExpressionSize::getOpName() const {
    return "$size";
}

在内部评估之后,您可以看到它只是从对象的getter中读取size()