如何按照给定的顺序排序并计算MongoDB中第二个文件的第一个文件?

时间:2016-12-28 08:27:37

标签: mongodb aggregation-framework

我希望在状态发生变化时,哪些成员不在场,以及哪个成员在场。

我给出的状态顺序数组如:

[{order:1,text:'CS'}, {order:2,text:'IP'}, {order:3,text:'AC'}]

所以我想按照这个数组进行排序,希望用每一堆文件执行一些操作

我的文件如:

{
  "count" : 2,
  "state" : "CS",
  "members" : [
    {
      "email" : "builuu1998@gmail.com",
      "date" : ISODate("2016-12-24T03:39:05.720Z")
    },
    {
      "email" : "bactv.hn@gmail.com",
      "date" : ISODate("2016-12-25T02:32:48.698Z")
    }
  ]
},
{
  "count" : 1,
  "state" : "AC",
  "members" : [
    {
      "email" : "builuu1998@gmail.com",
      "date" : ISODate("2016-12-24T03:39:05.720Z")
    }
  ]
},
  {
    "count" : 3,
    "state" : "IP",
    "members" : [
      {
        "email" : "builuu1998@gmail.com",
        "date" : ISODate("2016-12-24T03:39:05.720Z")
      },
      {
        "email" : "bactv.hn@gmail.com",
        "date" : ISODate("2016-12-25T02:32:48.698Z")
      },
      {
        "email" : "abc.hn@gmail.com",
        "date" : ISODate("2016-12-25T02:32:48.698Z")
      }
    ]
  }

所以我想知道哪个成员不是从一个州到另一个州以及哪些成员在场。

在我的考试中,第一州至第二州意味着(CS - IP):出席2名成员而不出席1名成员

{
"state": "CS_IP",
"present": [
  {
    "email" : "builuu1998@gmail.com",
    "date" : ISODate("2016-12-24T03:39:05.720Z")
  },
  {
    "email" : "bactv.hn@gmail.com",
    "date" : ISODate("2016-12-25T02:32:48.698Z")
  }
],

"notPresent": [
  {
    "email" : "abc.hn@gmail.com",
    "date" : ISODate("2016-12-25T02:32:48.698Z")
  }
]
}

和第二状态到第三状态意味着(IP-AC):存在1个成员而不存在2个成员

{"state": "IP_AC",
"present": [
  {
    "email" : "builuu1998@gmail.com",
    "date" : ISODate("2016-12-24T03:39:05.720Z")
  }
],

"notPresent": [
  {
    "email" : "bactv.hn@gmail.com",
    "date" : ISODate("2016-12-25T02:32:48.698Z")
  },
  {
    "email" : "abc.hn@gmail.com",
    "date" : ISODate("2016-12-25T02:32:48.698Z")
  }
]}

如何使用aggregate查询实现此目的,因为在此阶段完成后我需要一些聚合操作

1 个答案:

答案 0 :(得分:0)

对于["IP", "AC"]

,您可以为每个“情侣”状态执行一个聚合请求
db.exams.aggregate([{
    $match: {
        "state": {
            $in: ["IP", "AC"]
        }
    }
}, {
    "$group": {
        "_id": 1,
        "group1": { "$first": "$members" },
        "group2": { "$last": "$members" }
    }
}, {
    "$project": {
        "present": { "$setIntersection": ["$group1", "$group2"] },
        "notPresent": {
            $setUnion: [
                { "$setDifference": ["$group1", "$group2"] },
                { "$setDifference": ["$group2", "$group1"] }
            ]
        }
    }
}])

请注意,这只适用于2个匹配的元素(此处为["IP", "AC"]),因为我们必须创建两个新字段group1& group2$setIntersection$setDifference(因为$group$setIntersection$setDifference没有{ "_id": 1, "present": [ { "email": "builuu1998@gmail.com", "date": ISODate("2016-12-24T03:39:05.720Z") } ], "notPresent": [ { "email": "abc.hn@gmail.com", "date": ISODate("2016-12-25T02:32:48.698Z") }, { "email": "bactv.hn@gmail.com", "date": ISODate("2016-12-25T02:32:48.698Z") } ] }

上面的查询将给出:

private void showStatus(){
   mtc.setText(statusText);
}