如何将元素推入猫鼬中另一个数组内的对象内的数组中?

时间:2020-10-24 00:27:16

标签: javascript database mongodb mongoose mongoose-schema

我正在使用Expressjs,Mongodb和Mongoose开发服务器。我需要将一个元素(字符串)推入对象(朋友)内部的“ tweets”数组中,该对象又在“用户”对象中的“朋友”数组中,该对象在“用户”文档中采集。这是Mongodb集合中我的文档的示例:

{
    "loggedIn": true,
    "_id": "5f91ef0ce75d3b1d40539da0",
    "username": "username",
    "email": "a@h.com",
    "password": "$2a$10$9krWS9Kq5024lRTexqaweePrn8aughepqTkaj3oA48x0fJ2ajd79u",
    "dateOfBirth": "2002-12-07",
    "gender": "male",
    "friends": [
        {
            "tweets": [],
            "_id": "5f91effae75d3b1d40539da7",
            "username": "Jonas"
        },
        
    ],
    "__v": 0
}

我需要首先从“用户”数组中选择指定的用户名,然后访问该用户内的“朋友”数组,然后选择正确的朋友对象,最后在该数组中的$ position:0上发布推文。我试图实现此代码中所示的方法,并且可以使用给定的friendUsername访问朋友对象

await Users.updateOne(
      { username: req.params.username },
      {
        $push: {
          friends: {
            $elemMatch: {
              username: req.params.friendUsername,
            },
          },
        },
      }
    );

现在的问题是如何访问$ elemMatch内的“ tweets”数组并将req.body.tweet推送到$ position:0?

1 个答案:

答案 0 :(得分:0)

这是解决您的问题的方法,首先我将重新定义定义架构的方式。

我的User模式如下所示

User.js

const mongoose = require('mongoose')

const UserSchema = mongoose.Schema({
 ...
 friends: {
    type: [{
       type: mongoose.Schema.Types.ObjectId,
       ref: 'User'
    }],
    required: true,
    default: []
  },
  tweets: {
    type: [{
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Tweet'
    }],
    required: true,
    default: []
  },
 ...
}, {timestamps: true})

module.exports = mongoose.model('User', UserSchema)

User.js

const mongoose = require('mongoose')

const TweetSchema = mongoose.Schema({
 ...
 text: {
    type: String,
    required: true
  },
 tweeter: {
    type: mongoose.Schema.Types.ObjectId,
    required: true,
    ref: 'User'
 },
 likes: {
    type: [{
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    }],
    required: true,
    default: []
  },
 ...
}, {timestamps: true})

module.exports = mongoose.model('Tweet', TweetSchema)

这假设每个用户都可以拥有推文,并且User可以与另一个User成为朋友

现在,如果有人发推文,您可以做类似的事情

const Tweet = require('./Tweet.js')
const User = require('./User.js')

let tweet = new Tweet({
    text: "My first tweet!",
    tweeter: "ID Of user who is posting the tweet"
})

tweet.save()

// Now update the user who tweeted
User.findOneAndUpdate()
User.updateOne({ _id: "ID Of user who is posting the tweet" }, { $push: { tweets: tweet._id } })

现在,无论何时您请求用户,都会引用其所有朋友,还将引用其所有推文!如果您想查看实际的推文,则使用类似.populate()的东西,这里是.populate() https://mongoosejs.com/docs/populate.html

的文档

请记住,仅返回实际的ids确实是一个好习惯,并且您的前端会负责从其视角端点请求适当的对象。而且,如果您希望减少网络呼叫,那么前端将缓存数据。

如果上述方法没有帮助,并且您仍然希望通过架构实现目标,那么类似的事情应该起作用(假设您的架构称为User

let tweetObj = {}
User.updateOne({_id: 'your userid'}, {$push: {"friends.$.tweets": tweetObj}})

注意:我已经省略了回调,因为它们与问题无关