【问题标题】:Mongoose Mongodb querying an array of objectsMongoose Mongodb 查询对象数组
【发布时间】:2014-05-13 10:24:30
【问题描述】:

在使用 Mongoose 查询数组时,我很难得到我期望看到的结果。一个用户可以有许多与他/她的帐户相关联的房间。房间对象存储在集合中附加到用户的数组中。只有一个集合称为用户。

考虑用户和房间的以下两种模式:

用户架构

var userSchema = mongoose.Schema({

local            : {
    username     : String,
    email        : String,
    password     : String,
    rooms        : {type:Array, default: []}
}  


});

房间架构

var roomSchema = mongoose.Schema({

     name: String

});

这是我尝试过的查询:

var User = require('../models/user');

User.find({ 'rooms.name' : req.body.username  }, 
            { rooms: 
                { $elemMatch : 
                   { 
                     name: req.body.username 
                   } 
                } 
            }, function (err, user) {

        if (err){
            return done(err);
        }    

        console.log("user:::", user);

        if (user) {
            console.log("ROOM NAME FOUND");
            req.roomNameAlreadyInUse = true;
            next();

        } else {
            req.roomNameAlreadyInUse = false;
            console.log("ROOM NAME NOT FOUND");
            next();

        }

    });

问题是这个查询似乎总是返回一个空数组,即使它应该包含一些东西或者它应该什么也不返回。那么如何搜索所有用户房间数组以查看房间名称是否已经存在?

我也尝试了以下查询,但都没有成功:

User.find({local: {rooms: {$elemMatch: {name: req.body.username}}}}, function (err,     user) {

}



User.find({'local.rooms': {$elemMatch: {name: req.body.username}}}, function (err, user) {

}

我还应该指出,数据库已填充,因为我可以在 robomongo 中看到数组(在创建用户帐户时创建了 1 个元素)。

正在填充来自控制台输出的示例数据以显示数据库(包括 user.rooms 数组):

db.users.find() { "_id" : ObjectId("533c4db2b2c311a81be8a256"), "local" : { "password" : "$2a$08$0yQQJ2y0726kZtkWY5mAPOgZhacOmZn0Fd8DlausiuMB XE4ZblTXS”、“用户名”:“保罗”、“电子邮件”:“测试”、“房间”:[ {“名称”:“保罗”、“id”:ObjectId(“533c4db2b2c311a81be8a2 57") } ],“状态”:“活动”},“_v”:0 } { "_id" : ObjectId("533c4ddab2c311a81be8a258"), "local" : { "password" : "$2a$08$dC3CbDTkG5ozECDTu/IicO3Az0WdkzlGh2xDcb8j1CF/ FQhe5guZq”,“用户名”:“john”,“email”:“test2”,“rooms”:[ {“name”:“john”,“id”:ObjectId(“533c4ddab2c311a81be8a 259") } ],“状态”:“活动”},“_v”:0 }

【问题讨论】:

  • mongo shell 的“用户”集合中的数据实际上是什么样的?我还看到您的架构定义存在一些问题,并且您不清楚数据是否在一个或两个集合中。您可以将此添加到您的问题中。
  • 您发现我的 Schema Neil Lunn 有什么问题?数据都在一个集合中。
  • 其他问题更重要,所以如果您可以编辑会有所帮助。我在这里指的是“roomSchema”似乎没有被使用。它通常会在“userSchema”中引用。但我们需要看到的最重要的事情是您的一些数据。
  • @Neil Lunn,我添加了更多信息。我还将 find 调用更改为现在可以使用的 findOne(请参阅下面的答案。)当用户创建帐户时会使用 roomSchema。我确实尝试在用户模式数组中添加房间模式,如下所示 - 房间:[roomSchema]。但我无法让它发挥作用。我现在的做法对我来说很有意义,即当用户创建他们的帐户时,会创建一个用户模型和一个房间模型,然后将房间模型插入到用户模型中。我不确定这是否是最好的方法,或者它是否违反了最佳实践,但它似乎有效。

标签: node.js mongodb mongoose


【解决方案1】:

findOne 返回单个文档,其中find 返回一个游标。一旦你通过find的光标,你就到了最后,没有更多的文件了。

User.findOne({'local.rooms': {$elemMatch: {name: req.body.username}}}, (err,UserInfo) => {

        if (err){
            return res.status(400).json({Error:"Something went wrong please try again"})
        }    

        if (UserInfo) {
            console.log("ROOM NAME FOUND");
            req.roomNameAlreadyInUse = true;
            res.json({msg:"Room name found.",userData:UserInfo})

        } else {
            req.roomNameAlreadyInUse = false;
            console.log("ROOM NAME NOT FOUND");
            res.json({msg:"Room name not found."})
        }

    });

【讨论】:

    【解决方案2】:

    我将其更改为使用 findOne 而不是 find,它现在可以工作了。我不太清楚为什么这会有所作为。这是我使用的 findOne 函数:

    User.findOne({'local.rooms': {$elemMatch: {name: req.body.username}}}, function (err, user) {
    
            if (err){
                return done(err);
            }    
    
            if (user) {
                console.log("ROOM NAME FOUND");
                req.roomNameAlreadyInUse = true;
                next();
    
            } else {
                req.roomNameAlreadyInUse = false;
                console.log("ROOM NAME NOT FOUND");
                next();
    
            }
    
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-14
      • 2021-09-24
      • 1970-01-01
      • 2021-07-02
      • 1970-01-01
      • 2012-05-05
      • 1970-01-01
      相关资源
      最近更新 更多