如何从mongodb中的对象列表中获取最大值

时间:2014-05-09 08:56:03

标签: mongodb aggregation-framework

我有一份mongo文件:

"apps" : {
    "a" : {
        "last_login" : ISODate("2013-08-07T10:18:39.371Z")
    },
    "b" : {
        "last_login" : ISODate("2013-08-21T09:53:10.769Z")
    },
    "c" : {
        "last_login" : ISODate("2013-08-30T09:53:10.769Z")
    },
}

我想获得最高的last_login值?我该怎么做?

1 个答案:

答案 0 :(得分:0)

使用aggregation framework

db.collection.aggregate([
    { "$project": {
        "answer": { "$cond": [
            { "$gt": [ "$a.last_login", "$b.last_login" ] },
            { "$cond": [
                { "$gt": [ "$a.last_login", "$c.last_login" ] },
                { 
                    "key": { "$literal": "a" }, 
                    "last_login": "$a.last_login"
                },
                {
                    "key": { "$literal": "c" },
                    "last_login": "$c.last_login"
                }
            ]},
            { "$cond": [
                { "$gt": [ "$b.last_login", "$c.last_login" ] },
                {
                    "key": { "$literal": "b" },
                    "last_login": "$b.last_login"
                },
                {
                    "key": { "$literal": "c" },
                    "last_login": "$c.last_login"
                },
            ]}
        ]}
    }}
])

它有效,但它实际上很精神。所以在这里学习它的教训“不要以这种方式使用子文档”,而是使用数组

{
    "apps": [
      { "type": "a", "last_login": ISODate("2013-08-07T10:18:39.371Z") },
      { "type": "b", "last_login": ISODate("2013-08-21T09:53:10.769Z") },
      { "type": "c", "last_login": ISODate("2013-08-30T09:53:10.769Z") }
    ]
}

这使事情变得更加简单:

db.collection.aggregate(
    { "$unwind": "$apps" },
    { "$sort": { "apps.last_login": -1 } },
    { "$group": {
        "_id": "$_id",
        "answer": { "$first": "$apps" }
    }}
])

不是很容易。

注意: MongoDB 2.6中引入了$literal运算符。您可能会在网上找到一些引用 $const 作为备用运算符,但实际上并未正式支持,因为该运算符实际上是出于其他目的而存在。

您可以使用$cond运算符在早期服务器版本的MongoDB中执行完全相同的操作:

"key": { "$cond": [ 1, "a", 0 ] }

这可以作为$cond的结果参数实际上作为“文字”值传递,或“无论你在那里输入什么”,所以没有变量替换。