Как сгруппировать по каждому документу в массив документов - PullRequest
0 голосов
/ 22 сентября 2019

У меня следующая структура документа:

{
  "_id": "5d7e29896b149c50b01c88de",
  "submitted": true,
  "test": {
    "questions": [
      {
        "answerOptions": [
          "a",
          "b",
          "c",
          "d"
        ],
        "correctAnswers": [
          "a"
        ],
        "tags": [
          "tag1"
        ],
        "_id": "5d4cafa089fa358bcfc90b1c",
        "question": "Some question text 2",
        "category": "cat1",
        "__v": 0,
        "attempted": true,
        "answer": [
          "a"
        ],
        "isCorrect": true,
        "timeSpent": 3.28
      },
      {
        "answerOptions": [
          "a1",
          "b1",
          "c1",
          "d1"
        ],
        "correctAnswers": [
          "b1"
        ],
        "tags": [
          "tag1"
        ],
        "_id": "5d4cafa089fa358bcfc90b1d",
        "question": "Some question text",
        "category": "cat2",
        "__v": 0,
        "attempted": true,
        "answer": [
          "b1"
        ],
        "isCorrect": false,
        "timeSpent": 3.28
      }
    ],
    "_id": "5d7297af73e90c0bbfbd9575",

    "sections": [
      {
        "_id": "5d7297af73e90c0bbfbd9577",
        "name": "cat1"
      },
      {
        "_id": "5d7297af73e90c0bbfbd9576",
        "name": "cat2"
      }
    ],
    "duration": 30,
    "sectionalDuration": false,
    "isPaid": false,
    "isPublished": true,
    "createdAt": 1567791023,
    "lastModified": 1567791023,
    "__v": 0
  },

  "user": "5d4c7e91c2e50e7353f6cc07",
  "testRef": "5d7297af73e90c0bbfbd9575",
  "instituteRef": "5d46da097a00bcc2d9471700"
}

Вышеупомянутый документ представляет собой тест студента для идентификатора института 5d46da097a00bcc2d9471700 и идентификатора теста 5d7297af73e90c0bbfbd9575

То, чего я пытаюсь достичь, это: Получить список лучших N институтов для тестирования по средней оценке.Где для каждого института и для каждого теста в этом институте (один тест выше упомянутого документа).Получите среднюю оценку путем вычисления total correct answers (i.e isCorrect = true) / total tests (doc count of that institute)

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

[
  {"institute1":{avg:1}},
  {"institute2":{avg:2}},
]

Я не публикую его здесь напрямую.Я попытался создать несколько запросов в соответствии с моими знаниями об агрегации. Я новичок в структуре агрегирования, и я пытался искать в Интернете почти 15 дней, но ничего не получил от этого.

1 Ответ

0 голосов
/ 23 сентября 2019

Следующий запрос может дать нам ожидаемый результат:

db.collection.aggregate([
    {
        $group:{
            "_id":"$instituteRef",
            "totalCorrect":{
                $sum:{
                    $size:{
                        $filter:{
                            "input":"$test.questions",
                            "as":"question",
                            "cond":{
                                $eq:["$$question.isCorrect",true]
                            }
                        }
                    }
                }
            },
            "totalTests":{
                $sum:1
            }
        }
    },
    {
        $project:{
            "_id":0,
            "institute":"$_id",
            "avg":{
                $divide:["$totalCorrect","$totalTests"]
            }
        }
    },
    {
        $sort:{
            "avg":-1
        }
    },
    {
        $limit:10
    }
]).pretty()

Набор данных:

{
  "_id" : "5d7e29896b149c50b01c88de",
  "submitted" : true,
  "test" : {
    "questions" : [
      {
        "answerOptions" : [
          "a",
          "b",
          "c",
          "d"
        ],
        "correctAnswers" : [
          "a"
        ],
        "tags" : [
          "tag1"
        ],
        "_id" : "5d4cafa089fa358bcfc90b1c",
        "question" : "Some question text 2",
        "category" : "cat1",
        "__v" : 0,
        "attempted" : true,
        "answer" : [
          "a"
        ],
        "isCorrect" : true,
        "timeSpent" : 3.28
      },
      {
        "answerOptions" : [
          "a1",
          "b1",
          "c1",
          "d1"
        ],
        "correctAnswers" : [
          "b1"
        ],
        "tags" : [
          "tag1"
        ],
        "_id" : "5d4cafa089fa358bcfc90b1d",
        "question" : "Some question text",
        "category" : "cat2",
        "__v" : 0,
        "attempted" : true,
        "answer" : [
          "b1"
        ],
        "isCorrect" : false,
        "timeSpent" : 3.28
      }
    ],
    "_id" : "5d7297af73e90c0bbfbd9575",
    "sections" : [
      {
        "_id" : "5d7297af73e90c0bbfbd9577",
        "name" : "cat1"
      },
      {
        "_id" : "5d7297af73e90c0bbfbd9576",
        "name" : "cat2"
      }
    ],
    "duration" : 30,
    "sectionalDuration" : false,
    "isPaid" : false,
    "isPublished" : true,
    "createdAt" : 1567791023,
    "lastModified" : 1567791023,
    "__v" : 0
  },
  "user" : "5d4c7e91c2e50e7353f6cc07",
  "testRef" : "5d7297af73e90c0bbfbd9575",
  "instituteRef" : "5d46da097a00bcc2d9471700"
}

Выход:

{ "institute" : "5d46da097a00bcc2d9471700", "avg" : 1 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...