如何使用填充回调?

How do I use populate with callbacks?

User model

const Schema = mongoose.Schema

const userSchema = new Schema({
    username: { type: String, required: true },
    email: { type: String, reuired: true },
    password: { type: String, required: true },
    posts:[{ type: Schema.Types.ObjectId, ref: "Posts" }]
}, { timestamps: true })

Post model

const Schema = mongoose.Schema;

const postSchema = new Schema({
  title: { type: String, required: true },
  content: { type: String, required: true },
  user: { type: Schema.Types.ObjectId, ref: "User" },
}, { timestamps: true }

endpoint for getting all posts with all users information

    listPostsWithUsers: (req, res, next) => {
        Post.find({}, (error, posts) => {
            if (error) {
                return res.status(500).json({ error: "something went wrong" })
            } else if (!posts) {
                return res.status(400).json({ msg: "sorry no posts" })
            } else if (posts) {
                return res.status(200).json({ posts })
            }
        })
    }

输出应该是用户 object 返回的 posts,这样我就可以确定用户 post 编辑了哪个 post。

现在,我的问题是如何在上述端点中应用 populate() 方法。大多数示例都带有 exec() 函数,但我没有看到带有回调的示例。这是一个语法问题。

谢谢。

Update#1: 我目前得到的结果。

{
    "posts": [
        {
            "_id": "5e65cce5ebddec0c5cc925ab",
            "title": "Neil's Post",
            "content": "post by neil.",
            "createdAt": "2020-03-09T04:58:13.900Z",
            "updatedAt": "2020-03-09T04:58:13.900Z",
            "__v": 0
        },
        {
            "_id": "5e65cd32ebddec0c5cc925ad",
            "title": "Slash's post",
            "content": "post by slash.",
            "createdAt": "2020-03-09T04:59:30.180Z",
            "updatedAt": "2020-03-09T04:59:30.180Z",
            "__v": 0
        },
        {
            "_id": "5e65f430a989612916636e8d",
            "title": "Jimmy's post",
            "content": "post by jimmy",
            "createdAt": "2020-03-09T07:45:52.664Z",
            "updatedAt": "2020-03-09T07:45:52.664Z",
            "__v": 0
        }
    ]
}

Update#2

users collection.

{
    "users": [
    {
        "posts": [],
        "_id": "5e65ccbeebddec0c5cc925aa",
        "username": "Neil",
        "email": "neily888@gmail.com",
        "password": "b$AHHRKuCX3nakMs8hdVj0DuwD5uL0/TJwkJyKZYR/TXPTrIo9f80IW",
        "createdAt": "2020-03-09T04:57:35.008Z",
        "updatedAt": "2020-03-09T04:57:35.008Z",
        "__v": 0
    },
    {
        "posts": [],
        "_id": "5e65cd0eebddec0c5cc925ac",
        "username": "Slash",
        "email": "slash938@gmail.com",
        "password": "b$QQX/CFJjmpGdBAEogQ4XO.1e1ZowuPCX7pJcHTUav7NfatGgp6sa6",
        "createdAt": "2020-03-09T04:58:54.520Z",
        "updatedAt": "2020-03-09T04:58:54.520Z",
        "__v": 0
    },
    {
        "posts": [],
        "_id": "5e65f408a989612916636e8c",
        "username": "Jimmy",
        "email": "jimmy787@gmail.com",
        "password": "b$/DjwWYIlNswgmYt3vo7hJeNupfBdFGe7p77uisYUViKv8IdhasDC.",
        "createdAt": "2020-03-09T07:45:12.293Z",
        "updatedAt": "2020-03-09T07:45:12.293Z",
        "__v": 0
    }
    ]
}

Update#3:

usersController

const User = require("../models/User")

module.exports = {

  createUser: (req, res) => {
    User.create(req.body, (err, createdUser) => {
      if (err) console.log(err)
      res.json({createdUser})
    })
  },


  listUsers: (res) => {
    User.find({}, (err, users) => {
      if (err) console.log(err)
      res.json({users})
    })
  },

  getUser: (req, res) => {
    User.findById(req.params.id, (err, user) => {
      if (err) console.log(err)
        return res.json({user})
    })
  },

  updateUser: (req, res) => {

    const user = {
      username: req.body.username,
      email: req.body.email,
      password: req.body.password
    }

    User.findOneAndUpdate(req.params.id, user, { new: true }, (err, updatedUser) => {
        if (err) console.log(err)
        res.json({updatedUser})
    })
  },

  deleteUser: (req, res) => {
    User.findByIdAndDelete(req.params.id, (err, deleteduser) => {
      if (err) console.log(err)
        return res.status(200).json({ user: deleteduser })
    })
  }
}

postsController

const Post = require("../models/Post")

module.exports = {

  createPost: (req, res) => {

    const data = {
      title: req.body.title,
      description: req.body.description,
    }

    Post.create(data, (err, newPost) => {
      if (err) console.log(err);
        return res.status(200).json({ newPost })
    })
  },


  listPosts: (res) => {
    Post.find({}, async (err, posts) => {
      if (err) console.log(err);
        posts = await Post.populate(posts, {
          path: "user",
          model: "User"
        })
        return res.status(200).json({ posts })
    })
  },

  findPost: (req, res) => {
    Post.findById(req.params.id, (err, post) => {
      if (err) console.log(err);
        return res.json({ post })
      }
    )
  },

  updatePost: (req, res) => {

    const post = {
      title: req.body.title,
      description: req.body.description
    }

    Post.findByIdAndUpdate(req.params.id, post, { new: true },(err, updatedPost) => {
      if (err) console.log(err);
          return res.status(200).json({ updatedPost })
    })
  },

  deletePost: (req, res) => {
    Post.findByIdAndDelete(req.params.id, (err, deletedPost) => {
      if (err) console.log(err);
        return res.status(200).json({ deletedPost })
    })
  }
}

Update#4

router.get("/posts/:id", usersController.getUserPosts)`

    getUserPosts: (req, res) => {
        User.findById(req.params.id, async (err, user) => {
            if (err) {
                return res.status(500).json({ error: "Server error" })
            } else if (!user) {
                return res.status(400).json({ error: "No user" })
            } else if (user) {
                user = await User.populate("user", {
                  path: "posts",
                  model: "Post"
              })
            return res.status(200).json({ user })
         }
      })
    }

您可以在收到帖子后执行此操作:

  listPostsWithUsers: (req, res, next) => {
        Post.find({}, async (error, posts) => {
            if (error) {
                return res.status(500).json({ error: "something went wrong" })
            } else if (!posts) {
                return res.status(400).json({ msg: "sorry no posts" })
            } else if (posts) {
                posts = await Post.populate(posts, {
                  path: 'user',
                  model: 'User'
                });
                return res.status(200).json({ posts })
            }
        })
    }

我建议你使用 mongoose populate。

listPostsWithUsers : (req, res, next) => {
Post.find({}).populate('user').exec(function (err, data) {
 if (err) {
   console.log(err);
 } else {
     console.log(data);
   }
 })
}

You can refer this official mongoose populate document

您甚至可以使用 populate as

填充所需的任意多个字段
populate([{ path: 'user' }, { path: 'book', select: { author: 1 } }])

在填充中的 select 的帮助下,您可以投影所需的字段(仅从填充的集合中获取那些字段。)

编辑 1

  createPost: (req, res) => {

const data = {
  title: req.body.title,
  description: req.body.description,
  user: req.user._id,
}

Post.create(data, (err, newPost) => {
  if (err) console.log(err);
    return res.status(200).json({ newPost })
})

您需要在创建时在 post 中添加用户字段。 从令牌或查询中获取用户 ID,您就可以开始了。

编辑 2

getUserPosts: (req, res) => {
    User.findById(req.params.id).populate([{ path: 'posts' }])
     .exec(function (err, data) {
       if (err) {
        console.log(err);
       } else {
          console.log(data);
        }
    });
}

您正在用户模块中查找数据并且想要填充 post 数据,因此您只需说明要填充哪个字段,因为您已经通过添加 ref 在字段上定义了要引用的模型在猫鼬模式中使用该字段。

getUserPosts: (req, res) => {
    User.findById(req.params.id, async (err, user) => {
        if (err) {
            return res.status(500).json({ error: "Server error" })
        } else if (!user) {
            return res.status(400).json({ error: "No user" })
        } else if (user) {
            user = await User.populate("posts")
        return res.status(200).json({ user })
     }
  })
}

这应该也适合你。