MongoDB聚合合并字段

MongoDB聚合合并字段,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一个mongo数据库,我想“加入”其中的两个,然后合并其他一些字段: 让我们看看模式: 学生模式(和数据): 和主题模式: { "_id": ObjectId("5fbd4e6881b1313de790b56b"), "course": 3, "teacher": "John Smith", "name": "Math",

我有一个mongo数据库,我想“加入”其中的两个,然后合并其他一些字段: 让我们看看模式:

学生模式(和数据):

和主题模式:

{
    "_id": ObjectId("5fbd4e6881b1313de790b56b"),
    "course": 3,
    "teacher": "John Smith",
    "name": "Math",

},
{
    "_id": ObjectId("5fcb63fa8814d96876c687bf"),
    "name": "IT",
    "course": 8,
    "teacher": "John Peter",

}
我想对学生的科目(所有信息)进行查询,如果学生在科目中有其他字段,如
passed
将其添加到科目子文档中

以下是我到目前为止的疑问:

db.students.aggregate([
{
    $match: 
        {
            _id : ObjectId('5fbd564981b1313de790b580')
        }
},
{
    $lookup : 
        {
            from : "subjects",
            localField : "subjects._id",
            foreignField : "_id", 
            as : "FoundSubject"
        }
}
]);
正确地创建了“连接”,但仍然缺少合并,结果是:

{
    "_id": ObjectId("5fbd564981b1313de790b580"),
    "name": "John Doe",
    "age": "21",
    "image": "https://XXXX/481.png",
    "subjects": [
        {
            "_id": ObjectId("5fbd4e6881b1313de790b56b"),
            "passed": true,
        },
        {
            "_id": ObjectId("5fcb63fa8814d96876c687bf"),
        }
    ],
    "__v": NumberInt("1"),
    "FoundSubject": [
        {
            "_id": ObjectId("5fbd4e6881b1313de790b56b"),
            "course": 3,
            "teacher": "John Smith",
            "name": "Math"
        },
        {
            "_id": ObjectId("5fcb63fa8814d96876c687bf"),
            "name": "IT",
            "course": 8,
            "teacher": "John Peter"
        }
        
    ]
}
但是我想要:

{
    "_id": ObjectId("5fbd564981b1313de790b580"),
    "name": "John Doe",
    "age": "21",
    "image": "https://XXXX/481.png",
    "subjects": [
        {
            "_id": ObjectId("5fbd4e6881b1313de790b56b"),
            "course": 3,
            "teacher": "John Smith",
            "name": "Math",
            "passed": true,
        },
        {
            "_id": ObjectId("5fcb63fa8814d96876c687bf"),
            "name": "IT",
            "course": 8,
            "teacher": "John Peter"
        }
    ],
    "__v": NumberInt("1"),
}
添加合并数据和字段“已通过”。如何才能做到这一点? 我是来自MySQL的MongoDB新手


谢谢

您需要合并这两个对象,在
$lookup
之后添加到stage下方

3.4版的MongoDB

  • $map
    迭代
    学生
    数组的循环
  • $reduce
    要迭代
    FoundSubject
    数组的循环,请检查条件是否匹配,然后返回必填字段,否则返回初始值
  • $project
    从结果中删除
    FoundSubject


4.4版的MongoDB版本

  • $map
    迭代
    学生
    数组的循环
  • $filter
    FoundSubject
    数组中获取匹配文档,
    $first
    从filter返回的数组中获取第一个对象
  • $mergeObjects
    将当前对象与筛选器中找到的结果对象合并
  • 使用
    $$remove

在游乐场上工作正常,但在我的数据库上出现错误:>[error]无法识别的表达式“$mergeObjects”可能是数据库版本问题?mongodb的版本是什么?您在哪里执行此查询?MongoDB shell v3.4.24版。直接从mongo shell:断言:命令失败:{“ok”:0,“errmsg”:“无法识别的表达式'$mergeObjects'”,“代码”:168,“代码名”:“InvalidPipelineOperator”}:聚合失败_getErrorWithCode@src/mongo/shell/utils.js:25:13doassert@src/mongo/shell/assert.js:16:14 DBCollection.prototype。aggregate@src/mongo/shell/collection.js 2020-12-09T13:08:32.619+0000 E查询[thread1]错误:命令失败:{“errmsg”:“无法识别的表达式“$mergeObjects”,好的$mergeObjects支持3.6版,以及$first start from 4.4版,我将很快更新3.4版的答案。@MarcoMartin我已经更新了3.4版的答案,您可以查看。
{
    "_id": ObjectId("5fbd564981b1313de790b580"),
    "name": "John Doe",
    "age": "21",
    "image": "https://XXXX/481.png",
    "subjects": [
        {
            "_id": ObjectId("5fbd4e6881b1313de790b56b"),
            "course": 3,
            "teacher": "John Smith",
            "name": "Math",
            "passed": true,
        },
        {
            "_id": ObjectId("5fcb63fa8814d96876c687bf"),
            "name": "IT",
            "course": 8,
            "teacher": "John Peter"
        }
    ],
    "__v": NumberInt("1"),
}
  {
    $addFields: {
      subjects: {
        $map: {
          input: "$subjects",
          as: "s",
          in: {
            $reduce: {
              input: "$FoundSubject",
              initialValue: {},
              in: {
                $cond: [
                  { $eq: ["$$s._id", "$$this._id"] },
                  {
                    _id: "$$this._id",
                    course: "$$this.course",
                    name: "$$this.name",
                    teacher: "$$this.teacher",
                    passed: "$$s.passed"
                  },
                  "$$value"
                ]
              }
            }
          }
        }
      }
    }
  },
  { $project: { FoundSubject: 0 } }
  // skipping your stages
  {
    $addFields: {
      FoundSubject: "$$REMOVE",
      subjects: {
        $map: {
          input: "$subjects",
          as: "s",
          in: {
            $mergeObjects: [
              "$$s",
              {
                $first: {
                  $filter: {
                    input: "$FoundSubject",
                    cond: { $eq: ["$$s._id", "$$this._id"] }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }