node.js Mongoose Mongodb 查询对象数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22806326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 17:06:16  来源:igfitidea点击:

Mongoose Mongodb querying an array of objects

node.jsmongodbmongoose

提问by Paulie

I am struggling to get what I expect to see when querying an array using Mongoose. A user can have many rooms associated with his/her account. The room objects are stored in an array attached to the user within the collection. There is only one collection called users.

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

Consider the following two Schemas for user and room:

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

USER SCHEMA

用户架构

var userSchema = mongoose.Schema({

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


});

ROOM SCHEMA

房间结构

var roomSchema = mongoose.Schema({

     name: String

});

This is the query I have tried:

这是我试过的查询:

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();

        }

    });

The problem is this query seems to always return an empty array even if it should contiain something or if it should return nothing. So how would I search through all users room arrays to see if the room name already exists?

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

I have also tried the following to queries but neither are successful:

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

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

}



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

}

I should also point out that the database is populated as I can see the array (which has 1 element created on user account creation) in robomongo.

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

Sample data from console output to show database is being populated (including user.rooms array):

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

db.users.find() { "_id" : ObjectId("533c4db2b2c311a81be8a256"), "local" : { "password" : "$2a$08$0yQQJ2y0726kZtkWY5mAPOgZhacOmZn0Fd8DlausiuMB XE4ZblTXS", "username" : "paul", "email" : "test", "rooms" : [ { "name" : "paul", "id" : ObjectId("533c4db2b2c311a81be8a2 57") } ], "status" : "active" }, "_v" : 0 } { "_id" : ObjectId("533c4ddab2c311a81be8a258"), "local" : { "password" : "$2a$08$dC3CbDTkG5ozECDTu/IicO3Az0WdkzlGh2xDcb8j1CF/ FQhe5guZq", "username" : "john", "email" : "test2", "rooms" : [ { "name" : "john", "id" : ObjectId("533c4ddab2c311a81be8a 259") } ], "status" : "active" }, "_v" : 0 }

db.users.find() { "_id" : ObjectId("533c4db2b2c311a81be8a256"), "local" : { "password" : "$2a$08$0yQQJ2y0726kZtkWY5mAPOgZhacOmZn0Fd8DlausiuMB","Xmailzd8DlausiuMBe",测试”,“房间”:[{“名称”:“保罗”,“ id”:ObjectId(“533c4db2b2c311a81be8a2 57”)}],“状态”:“活动”},“_v”:0}{“ _id” : ObjectId("533c4ddab2c311a81be8a258"), "local" : { "password" : "$2a$08$dC3CbDTkG5ozECDTu/IicO3Az0WdkzlGh2xDcb8j1CF/ FQhe5guZq", "", "user {“姓名”:“约翰”,“id”:ObjectId(“533c4ddab2c311a81be8a 259”)}],“状态”:“活动”},“_v”:0}

回答by Paulie

I changed it to use findOne instead of find and it works now. I am not too sure why this should make a difference. This is the findOne function I used:

我将其更改为使用 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();

        }

    });

回答by Binu

findOnereturns a single document, where findreturns a cursor. Once you go through the cursor of find, you are at the end, and there are no more documents.

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."})
        }

    });