我有一个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值?我该怎么做呢?
使用聚合框架:
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" }
}}
])
容易多了,不是吗?
注意: $literal
操作符是在MongoDB 2.6中引入的。您可能会在网上找到一些引用 $const
作为替代操作符,但这实际上并没有得到官方支持,因为该操作符实际上是为其他目的而存在的。
你可以做完全相同的事情在MongoDB的早期服务器版本使用 $cond
操作符代替:
"key": { "$cond": [ 1, "a", 0 ] }
$cond
的结果参数实际上作为"文字"值或"您在那里键入的任何内容"交付,因此没有变量替换。