用于以下关系的 MongoDb 嵌套数组查询

Posted

技术标签:

【中文标题】用于以下关系的 MongoDb 嵌套数组查询【英文标题】:MongoDb nested array query for following relationship 【发布时间】: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" 使用我的查询和上面的查询 【参考方案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 这行不通。我最近第二次问。 “谁在投票支持这些完全未经检验的错误答案?”

以上是关于用于以下关系的 MongoDb 嵌套数组查询的主要内容,如果未能解决你的问题,请参考以下文章

Mongodb:查询嵌套数组的大小

MongoDB 嵌套对象数组后查询

MongoDB 嵌套对象数组后查询

Mongodb查询过滤文档中的嵌套对象数组

如何使用 findOne 查询 mongodb 并排除数组中的一些嵌套字段

mongodb 查询求助,嵌套数组里面查东西