hyd*_*yde 2 javascript mongodb mongodb-query
我无法想出一个很好的方法来进行某个MongoDb查询.首先,这是我想要做什么样的查询.假设一个简单的数据库通过电子刷卡记录进入和退出事件(可能还有其他操作,无关紧要).所以有一个名为swipelog简单文档的集合,如下所示:
{
_id: ObjectId("524ab4790a4c0e402200052c")
name: "John Doe",
action: "entry",
timestamp: ISODate("2013-10-01T1:32:12.112Z")
}
Run Code Online (Sandbox Code Playgroud)
现在我想列出名称及其最后输入时间(以及我可能想要的任何其他字段,但下面的示例仅使用这两个字段).
这就是我现在所拥有的,作为MongoDb JavaScript控制台的"一线":
db.swipelog.distinct('name')
.forEach( function(name) {
db.swipelog.find( { name: name, action:"entry" } )
.sort( { $natural:-1 } )
.limit(1)
.forEach( function(entry) {
printjson( [ entry.name, entry.timestamp ] )
})
})
Run Code Online (Sandbox Code Playgroud)
其中印有以下内容:
[ "John Doe", ISODate("2013-10-01T1:32:12.112Z")]
[ "Jane Deo", ISODate("2013-10-01T1:36:12.112Z")]
...
Run Code Online (Sandbox Code Playgroud)
我认为上面有明显的缩放问题.如果有一百个名称,那么将对数据库进行1 + 100次查询.那么什么是获得"最后timestamp一个不同name" 的好/正确方法?如果更容易,更改数据库结构或添加一些集合是可以的.
att*_*ish 12
您可以使用聚合框架来实现此目的:
db.collection.aggregate(
[
{$match:
{action:'entry'}
},
{$group:
{_id:'$name',
first:
{$max:'$timestamp'}
}
}
])
Run Code Online (Sandbox Code Playgroud)
如果您可能在结果中包含其他字段,则可以使用$ first运算符
db.collection.aggregate(
[
{$match:
{action:'entry'}
},
{$sort:
{name:1, timestamp:-1}
},
{$group:
{_id:'$name',
timestamp: {$first:'$timestamp'},
otherField: {$first:'$otherField'},
}
}
])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1668 次 |
| 最近记录: |