Polaiah Bodeddula
Polaiah Bodeddula

Reputation: 158

Mongoose unable to get data from MongoDB database

I have a model (AccountModel.js) as below and the controller for it. i tried to change one document using postman but i am getting an empty array from the database event though the data is present.

let mongoose = require('mongoose')
let Schema = mongoose.Schema
var ObjectId = Schema.ObjectId

let mySchema = mongoose.Schema({
account_id:ObjectId,
account_key:String,
message:String,
created_at:Date,
updated_at:Date
})

let MySchema = module.exports = 
mongoose.model('account',mySchema);
module.exports.get = function(callback,limit){
MySchema.find(callback).limit(limit)
}

and AccountController as below to manage account db. i have consoled the query and the output from the database.

var mongoose = require('mongoose')
var Account = require('../models/AccountModel')
var ObjectId = mongoose.Types.ObjectId;


exports.setMessage = function(req,res){
query = {account_id:new ObjectId(req.body.acnt_id)}
console.log(query,"...")
Account.find(query,function(err,account_data){
    if(err){
        res.send(err)
    }
    else{
        try{

console.log(account_data,'setWelcomeMessage')
            account_data.message = 
req.body.welcomeMessage
            account_data.updated_at = new Date()
            account_data.save((err,data)=>{
                if(err){
                    console.log(err)
                    res.send(err)
                }
                res.send({"Status":"Success"})
            })
            res.send({"Status":"Success"})  
        }
        catch(e){
            //console.log(e)
            res.send({"Status":"Failed"})
        }
    }
})
}

below is the database

> db.account.find().pretty()
{
"_id" : ObjectId("5c18fea5c5a6a4ebf7999c0b"),
"account_id" : ObjectId("5c18fbefc5a6a4ebf7999c08"),
"account_key" : "UDS1500",
"message" : "testing message",
"created_at" : ISODate("2018-12-18T14:05:25.637Z"),
"updated_at" : ISODate("2018-12-18T14:05:25.637Z")
}
{
"_id" : ObjectId("5c18feffc5a6a4ebf7999c0c"),
"account_id" : ObjectId("5c18fbaac5a6a4ebf7999c07"),
"account_key" : "UDS1299",
"message" : "testing message2",
"created_at" : ISODate("2018-12-18T14:06:55.968Z"),
"updated_at" : ISODate("2018-12-18T14:06:55.968Z")
}

after calling from POSTMAN i am getting an empty array

Below is the request format

{
  "acnt_id":"5c18fbaac5a6a4ebf7999c07",
  "welcomeMessage":"test message 3!!"
}

console is as below

{ account_id: 5c18fbaac5a6a4ebf7999c07 } '...'
[] 'setWelcomeMessage'

what might be the problem in getting empty data? i have wasted a lot of time on this.

Upvotes: 1

Views: 164

Answers (4)

Polaiah Bodeddula
Polaiah Bodeddula

Reputation: 158

Thank you for you response. I found answer for my problem.

The reason is that the mongoose has created a model with the plural name. Which means, here i have named the model "account". But here in database it will create/connect to a collection with the name "accounts". I dont know the reason for mongoose not creating/connecting to a collection named "accounts". Since there is no collection named with "accounts" it is always giving me the empty result.

At last, i have changed the collection name to "accounts". Now it working fine.

Please comment the reason, mongoose creating/connecting to plural name of the given model.

Upvotes: 0

koteswararao pv
koteswararao pv

Reputation: 89

//getting from postman .... give the account id in postman
query = {account_id:req.body.acnt_id};
//there is match in DB--- getting the data
Account.find(query,function(err,account_data){
    if(err){
        res.send(err)
    }
u wana update 
    else{
Accoun.update({account_id:req.body.acnt_id},req.body
};
//on body what you enter in postman that will update and store on DB
IN MY KNOWLEDGE 
// just example 
Model.update

Updates all documents matching conditions using the update clause. All update values are casted to their appropriate types before being sent.

var conditions = { name: 'bourne' }
  , update = { $inc: { visits: 1 }}
  , options = { multi: true };

Model.update(conditions, update, options, callback);

function callback (err, numAffected) {
  // numAffected is the number of updated documents
})

Upvotes: -1

chridam
chridam

Reputation: 103475

The culprit is this line

query = {account_id:new ObjectId(req.body.acnt_id)}

where the statement new ObjectId(req.body.acnt_id) creates a new id (regardless of what you pass in the constructor) thus your query fails as there won't be any match in the db. You don't necessarily need to cast the acnt_id string to ObjectId as Mongoose does this for you under the hood, but if need be use

query = {account_id:mongoose.Types.ObjectId(req.body.acnt_id)}

otherwise

query = {account_id:req.body.acnt_id}

will suffice.


A better way to do the update would be to use the findOneAndUpdate method which does an atomic update of your model and mostly used when you want to update a single document in the db and return it to your application, so you can refactor your controller method to:

exports.setMessage = (req, res) => {
    const query = { 'account_id': req.body.acnt_id };
    const update = { 
        '$set': {
            'message': req.body.welcomeMessage,
            'updated_at': new Date(),
        }
    };
    const options = { 'new': true };

    Account.findOneAndUpdate(query, update, options, (err, account_data) => {
        if (err){
            res.send(err)
        }
        else {
            console.log(account_data); // logs the updated account document
            res.send({"Status":"Success"})
        }
    });
}

Also, you can set timestamps in your schema where mongoose assigns createdAt and updatedAt fields to your schema and the type assigned is Date i.e.

let mySchema = mongoose.Schema({
    account_id: ObjectId,
    account_key: String,
    message: String,
}, { timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' } });

Upvotes: 2

BenSower
BenSower

Reputation: 1612

.find() returns an array, not a single element. Therefore i'd recommend using the .findOne() method instead.

Upvotes: 0

Related Questions