如何确定用户使用聚合收集了多少点

分享于2022年07月17日 aggregate mongodb mongoose node.js 问答
【问题标题】:如何确定用户使用聚合收集了多少点(How to determine how many points a user has collected using aggregate)
【发布时间】:2022-01-26 04:59:24
【问题描述】:

我有这个 Schema 结构

const QuizQuestionSchema = new Schema({
  course: { type: String, required: true, trim: true },
  point: { type: Number, required: true, trim: true, min: 1, max: 20 },
  question: { type: String, required: true, trim: true },
  codeBoard: { type: String, default: null, nullable: true },
  answers: { type: [String], required: true, trim: true },
  correctAnswer: { type: String, required: true, trim: true }
});

从客户端我得到文档的数组 ID 和选择的答案 [{id, answer}...] 。 我需要找出用户收集了多少分,如果匹配加分,则将正确答案与答案进行比较。如何使用聚合来完成?

例子

客户

[
  { id: "61bc09994da5e9ffe47fccb9", answer: "1 2 4 3 5" },
  { id: "61bc0af14da5e9ffe47fccbb", answer: "1 4 3 2" },
  ...
];

服务器文档

  {
    _id: new ObjectId("61bc09994da5e9ffe47fccb9"),
    course: 'JavaScript',
    point: 10,
    question: 'What will we see in the console ?',
    codeBoard: '...',
    answers: [ '1 2 4 3 5', '1 5 4 3 2', '2 1 4 3 5', '1 5 3 4 2' ],
    correctAnswer: '2 1 4 3 5',
    __v: 0
  },
  {
    _id: new ObjectId("61bc0af14da5e9ffe47fccbb"),
    course: 'JavaScript',
    point: 10,
    question: 'What will we see in the console ?',
    codeBoard: '...',
    answers: [ '1 4 3 2', '1 2 4 3', '1 2 3 4', '1 4 2 3' ],
    correctAnswer: '1 4 3 2',
    __v: 0
  }

  • 您的用户架构如何?您能否提供一个完整的数据示例?
  • 你可以再看看
  • 所以,您没有“用户”,客户端应用程序只是向您发送带有服务器文档 ID 的答案,对吗?如果是这样,您可以使用 this 之类的东西。谁我仍然不明白 answers 数组字段是什么...
  • 哦,我刚刚意识到 answers 数组字段可能是可能的选择 xD。我共享的游乐场应该可以工作。
  • 我用 ObjectId 更新了问题

【解决方案1】:

如果客户端发送带有所选答案的字符串中的每个问题 id,您应该将该数组映射到:

  {
    id: new ObjectId("61bc09994da5e9ffe47fccb9"),
    correctAnswer: "2 1 4 3 5"
  }

记得用以下方式定义 ObjectId:

const ObjectId = require('mongoose').Types.ObjectId;

然后在 $or 运算符中添加完整的数组,最后对每个匹配进行分组并添加点。

db.collection.aggregate({
  "$match": {
    $or: [
      {
        id: new ObjectId("61bc09994da5e9ffe47fccb9"),
        correctAnswer: "2 1 4 3 5"
      },
      {
        id: new ObjectId("61bc0af14da5e9ffe47fccbb"),
        correctAnswer: "1 4 3 2"
      },
      . . .
    ]
  }
},
{
  "$group": {
    "_id": null, // This means that every document is grouped, because there is no condition to group by
    "points": { 
      $sum: "$point"
    }
  }
})