【问题标题】:MongoDb nested array query for following relationship用于以下关系的 MongoDb 嵌套数组查询
【发布时间】:2014-03-22 23:26:52
【问题描述】:

假设我有一个用户模式:

UserSchema = new Schema({
name:               {
                      first: { type: String, trim: true },
                      last:  { type: String, trim: true }
                    },
username:           { type: String, trim: true, required: true },
email:              { type: String, trim: true, required: true },
hashed_password:    { type: String, trim: true, required: true },
profile_image:      { type: String, trim: true, default: 'default' },
join_date:          { type: Date,     required:true },
userFollows:        [ {
                        status  : { type: String, enum: [
                            'following',
                            'followed_by'
                      ]},
                        added   : { type: Date,   required:true },
                        user    : { type: Schema.ObjectId, ref: 'User'}
                    } ]
})

我需要将新的 userFollows 推送到此架构中,但我还需要检查用户当前没有关注用户(重复条目)但不确定如何执行此查询

我正在尝试使用的当前查询是:

User
.findOne(
        {  username: req.user.username },
        { "userFollows.user": { $not: req.body.userID } }
     )
.exec(function (err, currentUser) {

})

但它不起作用。

我想避免在执行查询并手动检查后循环 currentUser.userFollows 数组

我需要推送的最终 userFollows 对象如下所示:

{
  _id: ObjectId("53073acd9256e81e4d7b5d8e"),
  status: "followed_by",
  added: ISODate("2014-02-21T11:38:53.828Z"),
  user: ObjectId("51c6ec9fedc1230700000007")
}

【问题讨论】:

  • 只是一个猜测,但像 findOne{ username: req.user.username, "userFollows.user": { $ne: req.body.userID } }) 这样的东西应该可以工作。重要的区别是使用一个对象调用 findOne,而不是两个。
  • 我收到此错误:{"code":"InternalError","message":"Cannot read property 'userFollows' of null"} 使用我的查询和上面的查询

标签: arrays node.js mongodb mongoose mongodb-query


【解决方案1】:

有两种方法可以进行此更新(在 shell 语法中):

db.users.update( 
     { "username": req.user.username },
     { $addToSet : { userFollows : { _id: ObjectId("53073acd9256e81e4d7b5d8e"),
                                     status: "followed_by",
                                     added: ISODate("2014-02-21T11:38:53.828Z"),
                                     user: ObjectId("51c6ec9fedc1230700000007")
                                   }
                   }
     }
)

表示,对于这个用户,将这个对象添加到 userFollows 数组中(除非它已经存在)。

另一种方法是:

db.users.update( 
     { "username": req.user.username, "userFollows.user": { $ne: req.body.userID } },
     { $push : { userFollows : { _id: ObjectId("53073acd9256e81e4d7b5d8e"),
                                     status: "followed_by",
                                     added: ISODate("2014-02-21T11:38:53.828Z"),
                                     user: ObjectId("51c6ec9fedc1230700000007")
                                   }
                   }
     }
)

它说:对于这个还没有这个追随者的用户,$push这个对象。

显然您会填写适当的字段 - 我只是从您的问题中剪切并粘贴一些示例值以显示完整格式。

【讨论】:

    【解决方案2】:

    查看 this 关于在更新查询中向嵌套数组添加数据的信息。

    db.collection.update( 
        { username: req.user.username }, 
        { $addToSet: { "userFollows.user": req.user.usernameThatIAdd } }
     );
    

    【讨论】:

    • 如果我还需要添加状态和添加字段,这会起作用吗?最终的 userFollows 对象如下所示: { status: "followed_by", added: ISODate("2014-02-21T11:38:53.828Z"), user: ObjectId("51c6ec9fedc1230700000007"), _id: ObjectId("53073acd9256e81e4d7b5d8e") }
    • userFollows 不仅仅是一个用户名。所以,你建议的$addToSet 行不通。
    • 而且,您会发现它实际上在语法上不起作用。你会收到一个错误can't append to array using string field name: user。您不能将dot 语法与$addToSet 一起使用。
    • 加倍@WiredPrairie 这行不通。我最近第二次问。 “谁在投票支持这些完全未经检验的错误答案?”
    猜你喜欢
    • 2013-06-22
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    • 2011-07-12
    • 2015-06-29
    相关资源
    最近更新 更多