【问题标题】:MongoDB / Mongoose one-to-many relationshipMongoDB / Mongoose 一对多关系
【发布时间】:2020-06-12 15:44:31
【问题描述】:

为一个新项目处理数据库结构,并试图弄清楚 MongoDB / mongoose 中的一对多关系究竟是如何工作的。

所以考虑以下简单的结构:

我有一个项目表/模式,其中链接了多个图像:

const ProjectSchema = mongoose.Schema({
    _id: mongoose.Types.ObjectId, // Just the id,
    name: { type: String, required: true, trim: true,  maxLength: 60 },
    description: { type: String, required: false }, 
    images: [{ 
        type: Schema.Types.ObjectId, ref: 'Image'
    }]
});

然后是图像表/模式:

const ImageSchema = new Schema({
    _id: mongoose.Types.ObjectId, // Just the id,
    url: { type: String, unique: true, required: true }
    project: { 
        type: Schema.Types.ObjectId, ref: 'Project'
    }        
});

我想要图像和项目之间的一对多,所以我用项目 id 保存了一个图像:

const image = new Image(
        {
                project: project._id,
                _id: new mongoose.Types.ObjectId(),
                url: 'https://someurl',
        });        
        await image.save();

如果我随后找到此图像并填充项目字段 - 它很好地包含所有项目信息,但如果我找到此项目,则图像数组中没有任何内容(引用图像):

images: [{ 
        type: Schema.Types.ObjectId, ref: 'Image'
    }]

我认为使用 ref 您正在创建 Project 和 Image 之间的外键引用,然后 Image 应该具有链接的 Project 并且 Project 应该在数组中看到链接的图像。 不是这样还是我在这里遗漏了什么?

【问题讨论】:

  • 如何查询项目?

标签: mongodb mongoose


【解决方案1】:

您应该能够毫无问题地从项目中填充图像。

假设你有这个项目文件:

{
    "_id" : ObjectId("5e592a438b93764a40a81a96"),
    "images" : [
        ObjectId("5e592aba8b93764a40a81a98"),
        ObjectId("5e592ac78b93764a40a81a99")
    ],
    "name" : "Project 1",
    "__v" : 0
}

还有这些图片文件:

{
    "_id" : ObjectId("5e592ac78b93764a40a81a99"),
    "url" : "Url 2",
    "project" : ObjectId("5e592a438b93764a40a81a96"),
    "__v" : 0
},
{
    "_id" : ObjectId("5e592aba8b93764a40a81a98"),
    "url" : "Url 1",
    "project" : ObjectId("5e592a438b93764a40a81a96"),
    "__v" : 0
}

我们可以使用下面的代码来填充图片:

router.get("/projects/:id", async (req, res) => {
  const result = await Project.findById(req.params.id).populate("images");
  res.send(result);
});

这将给出如下结果:

{
    "images": [
        {
            "_id": "5e592aba8b93764a40a81a98",
            "url": "Url 1",
            "project": "5e592a438b93764a40a81a96",
            "__v": 0
        },
        {
            "_id": "5e592ac78b93764a40a81a99",
            "url": "Url 2",
            "project": "5e592a438b93764a40a81a96",
            "__v": 0
        }
    ],
    "_id": "5e592a438b93764a40a81a96",
    "name": "Project 1",
    "__v": 0
}

因此,对于您的情况,请检查您的项目文档是否真的包含带有图像文档对象 ID 的图像数组,并且您正确填充。

另外你不需要在 schema 中添加 _id 字段,mongodb 会自动生成 _id。

项目

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const ProjectSchema = Schema({
  name: { type: String, required: true, trim: true, maxLength: 60 },
  description: { type: String, required: false },
  images: [
    {
      type: Schema.Types.ObjectId,
      ref: "Image"
    }
  ]
});

module.exports = mongoose.model("Project", ProjectSchema);

图片

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const ImageSchema = new Schema({
  url: { type: String, unique: true, required: true },
  project: {
    type: Schema.Types.ObjectId,
    ref: "Project"
  }
});

module.exports = mongoose.model("Image", ImageSchema);

【讨论】:

  • 谢谢!但我的意思是 - 有这个模式结构,如果我添加一个引用项目的新图像,比如说:“项目”:ObjectId(“5e592a438b93764a40a81a96”),如果那个id的项目有这个图像自动出现在图像数组?当我查询像 const foundProject = await Project .find({ name: project.name }) .populate('category status creator images') 这样的项目时,它显示空图像数组 []
  • @RRob 您需要填充,如我在答案中所示。此外,当您创建新图像时,您应该将该图像 ID 添加到项目的图像数组中。我已经展示了示例文档。
  • 知道了,例如,当我创建链接到项目的新图像时,我必须始终明确地将其添加到项目中的图像数组中,对吗?
  • @RRob 是的,这是真的。
  • 听起来很有趣,如果你明天有空请做
猜你喜欢
  • 2015-10-25
  • 2014-01-21
  • 2014-08-15
  • 2014-09-25
  • 2015-04-07
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多