我的文档结构如下:
{
'_id' => 'Star Wars',
'count' => 1234,
'spelling' => [ ( 'Star wars' => 10, 'Star Wars' => 15, 'sTaR WaRs' => 5) ]
}
我想获得前N个文档(通过递减计数),但每个文档只有一个拼写(具有最高值的文档)。有没有办法用聚合框架来做到这一点?
我可以轻松获得前10名结果(使用$ sort和$ limit)。但是,我如何才能获得每个拼写一次?
例如,如果我有以下三个记录:
{
'_id' => 'star_wars',
'count' => 1234,
'spelling' => [ ( 'Star wars' => 10, 'Star Wars' => 15, 'sTaR WaRs' => 5) ]
}
{
'_id' => 'willow',
'count' => 2211,
'spelling' => [ ( 'willow' => 300, 'Willow' => 550) ]
}
{
'_id' => 'indiana_jones',
'count' => 12,
'spelling' => [ ( 'indiana Jones' => 10, 'Indiana Jones' => 25, 'indiana jones' => 5) ]
}
我要求排名前2的结果,我会得到:
{
'_id' => 'willow',
'count' => 2211,
'spelling' => 'Willow'
}
{
'_id' => 'star_wars',
'count' => 1234,
'spelling' => 'Star Wars'
}
(或其他相似之处)
谢谢!
答案 0 :(得分:2)
您使用对象的键作为值时,您设计的架构会使使用除MapReduce之外的任何内容变得困难。因此,我调整了您的架构以更好地匹配MongoDB的功能(在本例中也采用JSON格式):
{
'_id' : 'star_wars',
'count' : 1234,
'spellings' : [
{ spelling: 'Star wars', total: 10},
{ spelling: 'Star Wars', total : 15},
{ spelling: 'sTaR WaRs', total : 5} ]
}
请注意,它现在是一个具有特定键名spelling
的对象数组,以及total
的值(我不知道该数字实际代表的是什么,所以我调用了它在我的例子中总计。)
进入聚合:
db.so.aggregate([
{ $unwind: '$spellings' },
{ $project: {
'spelling' : '$spellings.spelling',
'total': '$spellings.total',
'count': '$count'
}
},
{ $sort : { total : -1 } },
{ $group : { _id : '$_id',
count: { $first: '$count' },
largest : { $first : '$total' },
spelling : { $first: '$spelling' }
}
}
])
spelling
,total
和count
。 total
进行排序,以便最后一次分组可以使用$first
$first
的{{1}}值,然后还返回_id
,因为它为管道展平,每个临时文档将包含count
字段。 结果:
count