Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js mongoose中朋友模式的建模?_Node.js_Mongodb_Mongoose_Mongodb Query_Aggregation Framework - Fatal编程技术网

Node.js mongoose中朋友模式的建模?

Node.js mongoose中朋友模式的建模?,node.js,mongodb,mongoose,mongodb-query,aggregation-framework,Node.js,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,当我在其他用户配置文件上时,如何对mongoose模式建模以获得这三个按钮 加朋友 请求 朋友 我的用户模式 const schema = new Mongoose.Schema({ firstName: { type: String, default: '', trim: true }, lastName: { type: String, default: '', trim: true }, }, { timestamps: true }) 我找不到这个的正确模型。。。另外,请在建

当我在其他用户配置文件上时,如何对mongoose模式建模以获得这三个按钮

  • 加朋友
  • 请求
  • 朋友
  • 我的用户模式

    const schema = new Mongoose.Schema({
      firstName: { type: String, default: '', trim: true },
      lastName: { type: String, default: '', trim: true },
    }, { timestamps: true })
    

    我找不到这个的正确模型。。。另外,请在建模后建议聚合…

    所以最后我做了它,我认为这可能是使用mongodb和mongoose进行聚合的最佳方式

    1.为用户创建模型

    2.为好友创建一个模型,该模型具有接受、拒绝、挂起和请求的枚举

    3.现在api调用-->假设我们有两个用户UserA和UserB。。。所以,当UserA请求UserB成为朋友时,我们就交了两个 文档,以便UserA可以看到请求的,UserB可以看到挂起的 同时,我们将这些文档的_id推送到用户的 朋友

    4.如果用户B接受请求

    5.如果用户B拒绝请求

    6.获取所有好友,并检查登录用户是否为该用户的好友


    这个问题有点晚了,但我的解决方案是:

  • 为用户创建“自参考”模型:
  • 现在,如果您想查询好友,可以使用聚合函数匹配好友列表中的所有用户:

    exports.getFriends = async (req, res) => {
      let {id} = req.params
      let user = await User.aggregate([
        { "$match": { "_id": ObjectId(id) } },
        { "$lookup": {
          "from": User.collection.name,
          "let": { "friends": "$friends" },
          "pipeline": [
            { "$match": {
              "friends.status": 1,
            }},
            { "$project": { 
                "name": 1, 
                "email": 1,
                "avatar": 1
              }
            }
          ],
          "as": "friends"
        }}, 
      ])
    
      res.json({
        user
      })
    }
    

    与创建友谊联接表相比,这种方法的一个优点是,您可以进行更小的查询,而这样做的成本会低一些。对我来说,这似乎更直观。但是,我对mongo还很陌生,所以我不确定最佳实践是什么。

    这个问题的答案应该对您有所帮助:假设您有用户A和用户B。当用户A在用户B的朋友列表中,用户B在用户A的列表中时,您可以定义朋友。挂起可以是当用户A请求成为用户B的朋友(因此用户B在用户A的列表中),但用户B未接受时(意味着用户A不在用户B的列表中)。我知道这很冗长,但我希望这能有所帮助。你能解释一下阻塞、取消阻塞吗?嗨,很抱歉寻求帮助,但是ObjectId。。。。引用当前loggedIn用户或您实际查看的配置文件?(也称为非您所有的个人资料)?如果阵列中有数千个朋友,这是否会成为一个问题?这会在mongodb上引起问题吗?很好的实现,但是为什么您有一个用于添加好友的枚举?如果两个用户之间没有友谊,我想这一条可以参考,不是吗?@OhadChaet只是为了进一步澄清问题。但这取决于你。:-)
        const friendsSchema = new Schema({
          requester: { type: Schema.Types.ObjectId, ref: 'Users'},
          recipient: { type: Schema.Types.ObjectId, ref: 'Users'},
          status: {
            type: Number,
            enums: [
                0,    //'add friend',
                1,    //'requested',
                2,    //'pending',
                3,    //'friends'
            ]
          }
        }, {timestamps: true})
        module.exports = mongoose.model('Friends', friendsSchema)
    
        const docA = await Friend.findOneAndUpdate(
            { requester: UserA, recipient: UserB },
            { $set: { status: 1 }},
            { upsert: true, new: true }
        )
        const docB = await Friend.findOneAndUpdate(
            { recipient: UserA, requester: UserB },
            { $set: { status: 2 }},
            { upsert: true, new: true }
        )
        const updateUserA = await User.findOneAndUpdate(
            { _id: UserA },
            { $push: { friends: docA._id }}
        )
        const updateUserB = await User.findOneAndUpdate(
            { _id: UserB },
            { $push: { friends: docB._id }}
        )
    
        Friend.findOneAndUpdate(
            { requester: UserA, recipient: UserB },
            { $set: { status: 3 }}
        )
        Friend.findOneAndUpdate(
            { recipient: UserA requester: UserB },
            { $set: { status: 3 }}
        )
    
        const docA = await Friend.findOneAndRemove(
            { requester: UserA, recipient: UserB }
        )
        const docB = await Friend.findOneAndRemove(
            { recipient: UserA, requester: UserB }
        )
        const updateUserA = await User.findOneAndUpdate(
            { _id: UserA },
            { $pull: { friends: docA._id }}
        )
        const updateUserB = await User.findOneAndUpdate(
            { _id: UserB },
            { $pull: { friends: docB._id }}
        )
    
    User.aggregate([
      { "$lookup": {
        "from": Friend.collection.name,
        "let": { "friends": "$friends" },
        "pipeline": [
          { "$match": {
            "recipient": mongoose.Types.ObjectId("5afaab572c4ec049aeb0bcba"),
            "$expr": { "$in": [ "$_id", "$$friends" ] }
          }},
          { "$project": { "status": 1 } }
        ],
        "as": "friends"
      }},
      { "$addFields": {
        "friendsStatus": {
          "$ifNull": [ { "$min": "$friends.status" }, 0 ]
        }
      }}
    ])
    
    const Schema = mongoose.Schema;
    
    // Create Schema
    const UserSchema = new Schema({
       firstName: { 
          type: String, 
          required: true 
       },
       lastName: { 
          type: String, 
          required: true 
       },
       friends: [
          {
             user: {
               type: Schema.Types.ObjectId,
               ref: 'users',
             },
             status: Number,
             enums: [
               0,    //'add friend',
               1,    //'requested',
               2,    //'pending',
               3,    //'friends'
             ]
          }
       ]
    })
    
    exports.getFriends = async (req, res) => {
      let {id} = req.params
      let user = await User.aggregate([
        { "$match": { "_id": ObjectId(id) } },
        { "$lookup": {
          "from": User.collection.name,
          "let": { "friends": "$friends" },
          "pipeline": [
            { "$match": {
              "friends.status": 1,
            }},
            { "$project": { 
                "name": 1, 
                "email": 1,
                "avatar": 1
              }
            }
          ],
          "as": "friends"
        }}, 
      ])
    
      res.json({
        user
      })
    }