如何使用mongo查找与给定值匹配一周的键值?

时间:2014-12-02 07:42:46

标签: mongodb

我有以下收集结构 -

    [{
"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)将循环应用于结果以查找名称并检查状态。

任何人都可以帮助获得以上输出吗?

1 个答案:

答案 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

要理解此查询,最好逐个添加管道来聚合函数并检查结果。 希望这会有所帮助。