简体   繁体   English

猫鼬架构参考与嵌入数组

[英]mongoose schema reference vs embed array

I have an app with express and mongoose. 我有一个快递和猫鼬的应用程序。 I have two schemas, a Blog schema and a Comment schema. 我有两个架构,一个Blog架构和一个Comment架构。 I want to push a comment array from a form to a single blog, using RESTful routes. 我想使用RESTful路由将评论数组从表单推送到单个博客。 If I embed Comment schema in Blog schema it works, on the other hand if I reference the ObjectId of the Comment schema inside the Blog schema the code works for the first comment, then at the second one, the console throw a Validation Error: 如果我在Blog模式中嵌入Comment模式,则它起作用,另一方面,如果我在Blog模式中引用Comment模式的ObjectId,则该代码适用于第一个注释,然后在第二个注释中,控制台将抛出验证错误:

(node:5472) UnhandledPromiseRejectionWarning: 
Unhandled promise rejection (rejection id: 1): 
ValidationError: Blog validation failed: 
comments: Cast to [undefined] failed for value 
"[{
  "_id":"5a57374da3ba43156005c881",
  "text":"test1",
  "author":"test1",
  "__v":0
}]" 
at path "comments"

the object logged is the first comment I pushed to array 记录的对象是我推送到数组的第一个注释

This is the Blog schema (embed version) : 这是Blog模式(嵌入式版本)

//Embed

var mongoose = require("mongoose");

var comment = new mongoose.Schema({
    text: String,
    author: String
});

var blogSchema = new mongoose.Schema({
    name: String,
    image: String,
    description: String,
    comments: [comment]
});

module.exports = mongoose.model("Blog", blogSchema);

This is the Blog schema (reference version) : 这是Blog模式(参考版本)

// Reference

var mongoose = require("mongoose");

var blogSchema = new mongoose.Schema({
    name: String,
    image: String,
    description: String,
    comments: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: "Comment"
    }]
});

module.exports = mongoose.model("Blog", blogSchema);

And this is the Comment Schema : 这是Comment Schema

var mongoose = require("mongoose");

var commentSchema = new mongoose.Schema({
    text: String,
    author: String
});

module.exports = mongoose.model("Comment", commentSchema);

This is the Comment route I use to post new comment: 这是我用来发布新评论的评论路线

app.post("/blogs/:id/comments", function (req, res) {
    // find the correct campground
    Blog.findById(req.params.id, function (err, blog) {
        if (err) {
            console.log(err);
            res.redirect("/blogs");
        } else {
            Comment.create(req.body.comment, function (err, comment) {
                if (err) {
                    console.log(err);
                } else {
                    blog.comments.push(comment);
                    blog.save();
                    res.redirect("/blogs/" + blog._id);
                }
            });
        }
    });
});

Note that the Route works correctly and redirect to the "blogs/:id" page, if I console.log the blog or che comment object I have the correct output 请注意,如果我使用console.log博客或che评论对象,则路由可以正常工作并重定向到“ blogs /:id”页面,我的输出正确

At last, this is the form I use to post request: 最后,这是我用来发布请求的表格:

<div class="container">
    <div class="row">
        <h1 style="text-align: center;">Add a new Comment to <%= blog.name %></h1>
        <div style="width: 30%; margin:25px auto;">
            <form action="/blog/<%= blog._id %>/comments" method="POST">
                <div class="form-group">
                    <input class="form-control" type="text" name="comment[text]" placeholder="text">
                </div>
                <div class="form-group">
                    <input class="form-control"  type="text" name="comment[author]" placeholder="author">
                </div>
                <div class="form-group">
                    <button class="btn btn-lg btn-primary btn-block">Submit!</button>
                </div>
            </form>
            <a href="/blogs">Go Back</a>
        </div>
    </div>
</div>

EDIT I would prefer to use only the Ids of the comment instead of the full comment schema, but I don't know how to set the application up to do that. 编辑我宁愿只使用注释的ID而不是完整的注释架构,但是我不知道如何设置应用程序来做到这一点。

Same error is reported on mongoose github profile too: https://github.com/Automattic/mongoose/issues/5972 猫鼬github个人资料也报告了相同的错误: https : //github.com/Automattic/mongoose/issues/5972

For Reference version: After creating comment you can simply push id of created comment doc in blog document. 对于参考版本:创建评论后,您只需在博客文档中推送创建的评论文档的ID。

blog.comments.push(comment._id); 

or 要么

blog.comments.push(mongoose.Types.ObjectId(comment._id)); //to ensure the pushed id will be mongoose object id.

You must require mongoose for the step 2. 您必须在步骤2中要求猫鼬。

The Only way I found to solve this problem is refactor my code to look like this: 我发现解决此问题的唯一方法是重构代码,使其看起来像这样:

app.post("/blogs/:id/comments", function (req, res) {
    Comment.create(req.body.comment, function (err, comment) {
        if (err) {
            console.log(err);
        } else {
            Blog.findOne({"_id": req.params.id})
            .populate("comments")
            .exec(function (err, blog) {
                if (err) {
                    console.log(err);
                    res.redirect("/blogs");
                } else {
                    blog.comments.push(comment);
                    blog.save();
                    res.redirect("/blogs/" + blog._id);
                }
            });
        }
    });
});

However this not explain the behavior of the Schemas 但是,这不能解释模式的行为

Hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM