我正在尝试在某个位置获取包含几何体的文档,但是只想每个UUID返回一个文档。对于这个项目,在大多数情况下,每个UUID都有许多文档与$ near选择器匹配,因此我们得到许多具有相同UUID的文档。
任何人都可以协助完成以下查询,因此每个uuid只返回一个文档(最近的"日期")?
db.device.find(
{
location:
{ $near :
{
$geometry: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
$minDistance: 1000,
}
}
}
)
以下是该集合的一个示例:
{
"_id":ObjectId("5a4f1ff0fc6ded723265e6b0"),
"uuid":"user1",
"date": "2018-01-20 11:58:29.000",
"location":{
"type": "Point",
"coordinates":[
//remove for demo sake
]
}
},
{
"_id":ObjectId("5a62a245ce689f68245450a7"),
"uuid":"user2",
"date": "2018-01-20 11:58:07.000",
"location":{
"type": "Point",
"coordinates":[
//remove for demo sake
]
}
},
{
"_id":ObjectId("5a62a20fce689f7a14648c62"),
"uuid":"user1",
"date": "2018-01-20 11:58:39.000",
"location":{
"type": "Point",
"coordinates":[
//remove for demo sake
]
}
},
{
"_id":ObjectId("5a62a205ce689f7039203923"),
"uuid":"user1",
"date": "2018-01-20 11:58:49.000",
"location":{
"type": "Point",
"coordinates":[
//remove for demo sake
]
}
},
{
"_id":ObjectId("5a62a277ce689f703a3eacb3"),
"uuid":"user2",
"date": "2018-01-20 11:58:59.000",
"location":{
"type": "Point",
"coordinates":[
//remove for demo sake
]
}
}
答案 0 :(得分:2)
执行此类heavier
操作时,您可以切换到使用aggregation
管道。
使用此输入:
{
"uuid": "user1",
"date": "2018-01-20 11:58:29.000",
"location": { "type": "Point", "coordinates":[-0.17818, 51.15609] }
},
{
"uuid": "user2",
"date": "2018-01-20 11:58:07.000",
"location": { "type": "Point", "coordinates":[2.35944, 48.72528] }
},
{
"uuid": "user1",
"date": "2018-01-20 11:58:39.000",
"location": { "type": "Point", "coordinates": [1.45414, 43.61132] }
},
{
"uuid": "user1",
"date": "2018-01-20 11:58:49.000",
"location": { "type": "Point", "coordinates":[-6.24889, 53.33306] }
},
{
"uuid": "user2",
"date": "2018-01-20 11:58:59.000",
"location": { "type": "Point", "coordinates":[-3.68248, 40.47184] }
}
使用此索引:
db.device.createIndex( { location : "2dsphere" } )
此管道应该执行您想要的任务:
db.device.aggregate([
{ $match: { location: { $geoWithin: { $centerSphere: [ [ -0.17818, 51.15609 ], 0.1232135647961246 ] } } } },
{ $sort: { "date": -1 } },
{ $group: { _id: { uuid: "$uuid" }, users: { $push: { "uuid": "$uuid", "date": "$date", "location": "$location" } } } },
{ $project: { user: { $arrayElemAt: ["$users", 0] } } }
])
我首先将find/$near
运算符调整为等效聚合($geoWithin / $centerSphere)。它匹配0.123弧度范围内的位置(488公里(0.123 * 3963.2))。
然后我直接按日期排序,这样当文档将按用户分组时,我将能够轻松选择每个用户的第一个。
然后我按用户分组。
最后对于每个用户,因为我有$group
生成的值,这是一个用户文档数组(已排序),我只是用$arrayElemAt提取数组的第一项。< / p>
这会产生:
{
"_id" : { "uuid" : "user2" },
"user": {
"uuid": "user2",
"date": "2018-01-20 11:58:07.000",
"location": { "type": "Point", "coordinates": [ 2.35944, 48.72528 ] }
}
}
{
"_id": { "uuid" : "user1" },
"user": {
"uuid": "user1",
"date": "2018-01-20 11:58:49.000",
"location": { "type": "Point", "coordinates": [ -6.24889, 53.33306 ] }
}
}