我有以下收集结构 -
[{
"runtime":1417510501850,
"vms":[{
"name":"A",
"state":"on",
},{
"name":"B",
"state":"off",
}]
},
{
"runtime":1417510484000,
"vms":[{
"name":"A",
"state":"on",
}, {
"name":"B",
"state":"off",
}]
},{
"runtime":1417510184000,
"vms":[{
"name":"A",
"state":"off",
}, {
"name":"B",
"state":"off",
}]
},{
"runtime":1417509884000,
"vms":[{
"name":"A",
"state":"on",
}, {
"name":"B",
"state":"off",
}]
},{
"runtime":1416905084000,
"vms":[{
"name":"A",
"state":"on",
}, {
"name":"B",
"state":"off",
}]
}
]
这两个文件之间的差异是5分钟,由运行时间表示。 我有很多这样的文件。
我想找到状态为一周的名字。唯一的条件是状态应该是关闭一周(不应该有单个值' on' for key state)。
e.g。在上面的数据中,如果名称' B'离开一周(通过将1417510501850视为当前时间戳),那么我的预期输出将是 -
{
"name":"B",
"state":"off"
}
目前我正在关注 -
1)查找状态为“关闭”的文档。大于1周使用(currentTimestamp- 60 * 60 * 24 * 7) 2)将循环应用于结果以查找名称并检查状态。
任何人都可以帮助获得以上输出吗?
答案 0 :(得分:1)
我认为查询应该是这样的
db.yourcollection.aggregate([{$unwind: "$vms"}, //unwind for convenience
{$match: {"vms.state": {$eq: "off"}, runtime: {$lt: Date.now() - 7*24*60*60*1000}}}, //filter
{$project: {name: "$vms.name", state: "$vms.state"}}]) //projection
<强>更新强>
这是更正后的查询,只能获取一周内没有“开启”状态的文档。这有点困难,请参阅评论
db.yourcollection.aggregate([{$unwind: "$vms"}, //unwind for convenience
{$match: {runtime: {$lt: Date.now() - 7*24*60*60*1000}}}, //filter for a period
{$project: {_id: "$vms.name", state: "$vms.state"}}, //projection so docs will be like {_id: "a", state: "on"}
{$group: {_id: "$_id", states: {$push: "$state"}}}, //group by id to see all states in array
{$match: {states: {$eq: "off", $ne: "on"}}}, //take only docs which have state "off" and not have state "on"
{$project: {_id: "$_id", state: {$literal: "off"}}}]) //and convert to required output
要理解此查询,最好逐个添加管道来聚合函数并检查结果。 希望这会有所帮助。