如何在不使用mongoose的情况下向MongoDB填充数据?

3
我正在进行一项大学项目,需要使用ObjectIds填充对象数组,但是我不能在我的项目中使用mongoose。我有两个集合 - subjectstudyProgramstudyProgram文档示例:
{
  _id: ObjectId('111'),
  name: "Study program 1"
  description: "Lorem ipsum dolor sit amet",
  language: "en",
  subjects: [
    {
      id: ObjectId('222'),
      optionality: "selective",
      credits: 8,
    },
    {
      id: ObjectId('333'),
      optionality: "selective",
      credits: 5
    },
  ],
}

示例 主题 文档:

{
  _id: ObjectId('222'),
  name: "Subject A",
  description: "Subject A description.",
},
{
  _id: ObjectId('333'),
  name: "Subject B",
  description: "Subject B description.",
}

我需要根据id,将subject集合中的适当文档填充到subjects数组中。基本上,我想要的结果是这样的:

{
  _id: ObjectId('111'),
  name: "Study program 1"
  description: "Lorem ipsum dolor sit amet",
  language: "en",
  subjects: [
    {
      
      _id: ObjectId('222'),
      name: "Subject A",
      description: "Subject A description.",
      optionality: "selective",
      credits: 8,
    },
    {
      _id: ObjectId('333'),
      name: "Subject B",
      description: "Subject B description.",
      optionality: "selective",
      credits: 5
    },
  ],
}

到目前为止,我尝试使用了以下 $lookup :

{
  $lookup: {
    from: "subject",
    localField: "subjects.id",
    foreignField: "_id",
    as: "subjects",
  }
}

但这会移除 optionalitycredits 属性。有没有一种方法可以在不使用 mongoose 的情况下实现这一点?谢谢。

1个回答

0
这是一种实现的方法。
db.studyProgram.aggregate([
  {
    "$lookup": {
      "from": "subject",
      "localField": "subjects.id",
      "foreignField": "_id",
      "as": "subjectDocs"
    }
  },
  {
    "$set": {
      "subjects": {
        "$map": {
          "input": "$subjects",
          "as": "subject",
          "in": {
            "$mergeObjects": [
              {
                "$first": {
                  "$filter": {
                    "input": "$subjectDocs",
                    "as": "doc",
                    "cond": {"$eq": ["$$doc._id", "$$subject.id"]}
                  }
                }
              },
              {
                "optionality": "$$subject.optionality",
                "credits": "$$subject.credits"
              }
            ]
          }
        }
      },
      "subjectDocs": "$$REMOVE"
    }
  }
])

mongoplayground.net上试一试。

如果"$first"不可用,请告诉您的系统管理员升级MongoDB!在此之前,这可能会起作用。

db.studyProgram.aggregate([
  {
    "$lookup": {
      "from": "subject",
      "localField": "subjects.id",
      "foreignField": "_id",
      "as": "subjectDocs"
    }
  },
  {
    "$set": {
      "subjects": {
        "$map": {
          "input": "$subjects",
          "as": "subject",
          "in": {
            "$mergeObjects": [
              {
                "$arrayElemAt": [
                  {
                    "$filter": {
                      "input": "$subjectDocs",
                      "as": "doc",
                      "cond": {"$eq": ["$$doc._id", "$$subject.id"]}
                    }
                  },
                  0
                ]
              },
              {
                "optionality": "$$subject.optionality",
                "credits": "$$subject.credits"
              }
            ]
          }
        }
      },
      "subjectDocs": "$$REMOVE"
    }
  }
])

mongoplayground.net上试一试。


非常感谢,我在mongoplayground上尝试了一下,它可以工作。然而,当我在我的项目中使用它时,我会收到一个错误,说:“未识别的表达式'$first'”。我相信这是因为我使用的是Mongo版本4.11.0,而$first在此版本中不可用。有没有其他操作符可以代替? - Marek Balvín
@MarekBalvín 是的,我看到"$first"只在那个版本的"$group"中可用。我通过使用"$arrayElemAt"更新了聚合管道。请查看更新后的答案。 - rickhg12hs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接