Mongodb查询 - 获取最新的一个和组结果

时间:2014-10-09 20:24:23

标签: mongodb mongodb-query

我有这样的文档结构

{
  lang: en,
  origin: 'Origin Value',
  key: 'Key',
  translation: 'Translated value',
  createdAt: <date>
}

因此有各种语言(en,de,it等),并且有很多密钥与不同的日期(createdAt字段)重复。我需要构建一个查询,它将为每种语言的每个键进行最新的本地化,并按语言对其进行分组。

预期结果:

{
  en: [
    {
      origin: 'Origin Value',
      key: 'Key',
      translation: 'Translated value',
      createdAt: <the latest one date for this particular key>     
    },
    {
      origin: 'Second Origin Value',
      key: 'Second Key',
      translation: 'Second Translated value',
      createdAt: <the latest one date for this particular key>     
    }
    ...
  ],
  de: [...],
  it: [...],
  ...
}

2 个答案:

答案 0 :(得分:1)

这应该以某种方式为您完成工作,因此首先按创建时对结果进行排序,并使用$ first运算符检索每个组的第一个结果:

db.dictionary.aggregate(
{$sort: {createdAt:-1}}, 
{$group: {_id:{lang: "$lang", key:"$key"}, createdAt:{$first:"$createdAt"}, origin: {$first:"$origin"}, translation: {$first:"$translation"}}})

据我所知,你不能在聚合框架中拥有动态字段名称,因此你不能在输出中使用语言键作为字段名称。

答案 1 :(得分:1)

在mongo shell V2.6.4上运行

var cursor = db.c.aggregate([ {
    $sort : {
        // sort to make sure the latest document of every group (lang, key) is at
        // first location.
        createAt : -1
    }
}, {
    $group : {
        _id : {
            lang : "$lang",
            key : "$key"
        },
        doc : {
            $first : "$$ROOT" // current entire document
        }
    }
}, {
    $group : {
        _id : "$_id.lang", // regroup to combine all keys into one lang
        body : {
            $push : {
                orgin : "$doc.origin",
                key : "$doc.key",
                translation : "$doc.translation",
                createAt : "$doc.createAt"
            }
        }
    }
} ]);

var result = {}; // store final result
cursor.forEach(function(doc) {
    result[doc._id] = doc.body; // aggregation pipeline can not process on key,
                                // this is a way to convert data to your
                                // expected format
});

如果在V2.6之前运行mongo shell,请在最后一条语句中考虑这种方式:

cursor.result.forEach(function(doc) {
    result[doc._id] = doc.body; 
});