【发布时间】:2014-06-22 11:19:55
【问题描述】:
我有以下结构的文档:
{
...,
trials:[ {...,
ref:[{a:1,b:2},{a:2,b:2},...]
},
{...,
ref:[{a:1,b:2}]
},
...,
]
}
ref 是一个保证长度至少为 1 的数组。
如果我想计算每个 ref 数组中每个元素的单独出现次数,我将使用以下聚合。 (这很好用)
db.cl.aggregate([
{$unwind:"$trials"},
{$unwind:"$trials.ref"},
{$group:{_id:"$trials.ref", count:{$sum:1}}}
])
现在我想做同样的事情,但只使用每个 ref 数组中的最后一个元素。我需要一种只选择聚合管道中每个数组的最后一个元素的方法。
我首先认为我可以添加一个中间步骤,通过执行以下操作来获取我想要分组的所有元素:
db.cl.aggregate([
{$unwind:"$trials"},
{$group:{_id:null,arr:{$push:"$trials.ref.-1"}}},...
])
我也尝试使用带有$match 的位置运算符。
db.cl.aggregate([
{$unwind:"$trials"},
{$match:{"trials.ref.$":-1}},...
])
或者尝试投影最后一个元素。
db.cl.aggregate([
{$unwind:"$trials"},
{$project:{ref:"$trials.ref.1"}}
])
这些都不能让我去任何地方。 $pop 运算符在聚合管道中无效。 $last 运算符在这里并不是很有用。
关于如何只使用ref 数组的最后一个元素有什么想法吗?我宁愿继续使用聚合框架,而不是使用 Map Reduce。
【问题讨论】:
-
比您想象的要棘手得多。见here
-
我完全意识到这是一个有趣的问题。我在这里只展示了我的一些尝试。我花了很长时间思考这个问题。我可以查询所有
ref数组并在本地进行计算,但我宁愿不这样做。 -
我引用了另一个问题,因为您面临的问题是“top-n”问题。你不能在聚合框架中
$slice。鉴于您想要做的事情,这是一个问题。您可以使用$first和$match层来模拟它,如图所示。但是没有简单的方法来获得每个分组数组的“n”个结果。这基本上就是你要问的。
标签: mongodb mapreduce aggregation-framework