我正在创建一个"模拟程序"我在MongoDB中保存了大约700个移动对象的位置。我保存集合中的所有位置,每个文档都是一个"移动对象"。至于好。
现在我的问题: 我想阅读700" Objects"中的所有位置。一个查询但位置的时间戳是可变的......
示例文档:
{
"_id" : ObjectId("59522479707c4fbf16b2f91b"),
"PuckId" : 0,
"Positions" : [
{
"time" : 0,
"x_pos" : 0,
"y_pos" : 0,
"state" : 1
},
{
"time" : 10,
"x_pos" : 5,
"y_pos" : 5,
"state" : 1
},
{
"time" : 20,
"x_pos" : 0,
"y_pos" : 20,
"state" : 1
},
{
"time" : 25,
"x_pos" : 5,
"y_pos" : 10,
"state" : 1
}
]
}
{
"_id" : ObjectId("59522660707c4fbf16b38701"),
"PuckId" : 1,
"Positions" : [
{
"time" : 1,
"x_pos" : 1,
"y_pos" : 0,
"state" : 1
},
{
"time" : 5,
"x_pos" : 5,
"y_pos" : 10,
"state" : 1
},
{
"time" : 8,
"x_pos" : 0,
"y_pos" : 2,
"state" : 1
},
{
"time" : 22,
"x_pos" : 5,
"y_pos" : 0,
"state" : 1
}
]
}
这是我到目前为止所获得的: (对于此示例,我试图在Timesamp 10中查询对象的位置)
db.getCollection('LogFileV2').aggregate([
{
$project: {
Positions:{
$filter: {
input: "$Positions", //{$slice: ["$Positions",1]}, *see below
as: "pos",
cond: {
$or: [{
$lt: ["$$pos.time", 10+1] //at Timestamp 10
}]
}
}
}
}
}
]);
那么我需要做些什么才能得到这个结果:
/* 1 */
{
"_id" : ObjectId("59522479707c4fbf16b2f91b"),
"Positions" : [
{
"time" : 10,
"x_pos" : 5,
"y_pos" : 5,
"state" : 1
}
]
}
/* 2 */
{
"_id" : ObjectId("59522660707c4fbf16b38701"),
"Positions" : [
{
"time" : 8,
"x_pos" : 0,
"y_pos" : 2,
"state" : 1
}
]
}
答案 0 :(得分:0)
对于最近的我会使用这样的东西:
db.getCollection('LogFileV2').aggregate([
{ "$match": { "Positions.time": { "$lte": 10 } } },
{ "$project": {
"Positions": {
"$map": {
"input": {
"$filter": {
"input": "$Positions",
"as": "pos",
"cond": { "$lte": [ "$$pos.time", 10 ] }
}
},
"as": "pos",
"in": {
"time": "$$pos.time",
"x_pos": "$$pos.x_pos",
"y_pos": "$$pos.y_pos",
"state": "$$pos.state",
"diff": { "$subtract": [ 10, "$$pos.time" ] }
}
}
}
}},
{ "$unwind": "$Positions" },
{ "$sort": { "_id": 1, "Positions.diff": 1 } },
{ "$group": {
"_id": "$_id",
"Positions": { "$first": "$Positions" }
}},
{ "$sort": { "_id": 1 } }
])
这给了你:
/* 1 */
{
"_id" : ObjectId("59522479707c4fbf16b2f91b"),
"Positions" : {
"time" : 10.0,
"x_pos" : 5.0,
"y_pos" : 5.0,
"state" : 1.0,
"diff" : 0.0
}
}
/* 2 */
{
"_id" : ObjectId("59522660707c4fbf16b38701"),
"Positions" : {
"time" : 8.0,
"x_pos" : 0.0,
"y_pos" : 2.0,
"state" : 1.0,
"diff" : 2.0
}
}
因此除了查询以消除不符合条件的文件之外,基本的改变是使用$map
以获得"差异"来自查询的价值。
然后我们基本上想要$sort
数组结果,并且只选择差异最小的那个。这是通过$first
管道阶段{/ 3}}获得的。
或者,您可以再次针对$group
值在$let
和$filter
内定义数组。在支持的情况下,这会更快:
db.getCollection('LogFileV2').aggregate([
{ "$match": { "Positions.time": { "$lte": 10 } } },
{ "$project": {
"Positions": {
"$let": {
"vars": {
"filtered": {
"$map": {
"input": {
"$filter": {
"input": "$Positions",
"as": "pos",
"cond": { "$lte": [ "$$pos.time", 10 ] }
}
},
"as": "pos",
"in": {
"time": "$$pos.time",
"x_pos": "$$pos.x_pos",
"y_pos": "$$pos.y_pos",
"state": "$$pos.state",
"diff": { "$subtract": [ 10, "$$pos.time" ] }
}
}
}
},
"in": {
"$arrayElemAt": [
{ "$filter": {
"input": "$$filtered",
"as": "f",
"cond": { "$eq": [ "$$f.diff", { "$min": "$$filtered.diff" } ] }
}},
0
]
}
}
}
}}
])