假设我有一个集合"帖子",并且帖子可以有评论,这些评论作为数组存储在帖子文档中,如下所示:
λ> :k Compose Const
Compose Const :: (k -> *) -> k -> k1 -> *
如果我想计算特定帖子的评论数量,我可以{
...
comments : [ ... ]
...
}
。但是,看一下bson二进制格式,看起来它实际上并不存储数组的大小,它只是一个带有键0,1,2的文档...
如果是这种情况,是否必须遍历所有评论来计算它们?这似乎效率低下,特别是如果你有很多帖子说超过1000条评论。
有一个明显的解决方法。只需将计数存储在文档中。
{ $size : "$comments" }
我很好奇mongo是否在幕后做了一件我不应该担心的问题。
感谢。
答案 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()
。