0

我有一个结构如下的文档:

{
  '_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'
}

(或类似的东西)

谢谢!

4

1 回答 1

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' }
        }
    }
])
  1. 展开所有数据,以便聚合管道可以访问数组的各种值
  2. 展平数据以包括管道所需的关键方面。在这种情况下,特定spellingtotal、 和count
  3. 在 上排序total,以便最后一个分组可以使用$first
  4. 然后,分组以便只返回$first每个的值_id,然后还返回count由于管道扁平化的方式,每个临时文档都将包含该count字段。

结果:

[
{
    "_id" : "star_wars",
    "count" : 1234,
    "largest" : 15,
    "spelling" : "Star Wars"
},
{
    "_id" : "indiana_jones",
    "count" : 12,
    "largest" : 25,
    "spelling" : "Indiana Jones"
},
{
    "_id" : "willow",
    "count" : 2211,
    "largest" : 550,
    "spelling" : "Willow"
}
]
于 2013-07-14T14:53:38.480 回答