Как Сортировать по заданному порядку и расчету 1-й документ со вторым в MongoDB?

Я хочу получить, какие члены не присутствуют при изменении состояния и какой член присутствует.

Мой заданный массив для государственного заказа, как:

[{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")
      }
    ]
  }

Поэтому я хочу знать, какие члены не присутствуют от одного государства к другому государству и какие члены присутствуют .

В моем экзамене от 1-го государства до 2-го государства средства (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")
  }
]
}

и 2-го государства к 3-му государству означает (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 ответ

  1. Вы можете выполнить один запрос агрегации на «пару» состояния, как это для ["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& group2to $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") }
        ]
    }