Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose return data inside _doc object

On mongoose find query execution, response data as multiple objects, the real data is in _doc property or field, its only occurs in some scenario. I can handle the data by getting Obj._doc.something, but i cant edit the data and save(mongoose model function). please help me to resolve this problem.

Note: Fields for schema has added dynamically.

PatientOrderMigration.find({ mrn: orderitem.mrn, visituid: orderitem.visituid },
function (err, orderDoc) 
{ 
//log data correctly.
console.log(orderDoc);
// undefined
console.log(orderDoc._id);
// correct data
console.log(orderDoc._doc._id);
}
like image 333
PrasathBV Avatar asked Feb 26 '18 12:02

PrasathBV


3 Answers

I know this is old but I had similar issue. To fix this problem use .lean().

The lean option tells Mongoose to skip hydrating the result documents. This makes queries faster and less memory intensive, but the result documents are plain old JavaScript objects (POJOs), not Mongoose documents.

so your query would be:

PatientOrderMigration.find({ mrn: orderitem.mrn, visituid: orderitem.visituid }).lean()
like image 78
TSlegaitis Avatar answered Nov 14 '22 04:11

TSlegaitis


The origin problem is that the find method returns an array, which is pointed out by the accepted answer. But the title "Mongoose return data inside _doc object" relates to another frequent error. So I want to resume my research here.


When you using Mongoose API to query data (find, findOne, findById ..), Mongoose will give you an instance of Mongoose Document class in the response, which is different from your Javascript object.

You have some options to get your Javascript object, as described in the document :

  • using lean() method : Check out the document here
  • using toObject() method : Check out the document here

I created a test project to demonstrate these methods, feel free to test this :

const mongoose = require('mongoose');

// connect to database
mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true, useUnifiedTopology: true });

// define the schema 
const kittySchema = new mongoose.Schema({
    name: String

    // this flag indicate that the shema we defined is not fixed, 
    // document in database can have some fields that are not defined in the schema
    // which is very likely
}, { strict: false });

// compile schema to model
const Kitten = mongoose.model('Kitten', kittySchema);

test();
async function test() {


    // test data
    const dataObject = { name: "Kitty 1", color: "red" };
    const firstKitty = new Kitten(dataObject); // attribute color is not defined in the schema

    // save in database
    firstKitty.save();

    // find the kitty from database
    // mongoose return a document object, which is different from our data object
    const firstKittyDocument = await Kitten.findOne({ name: "Kitty 1" });
    console.log("Mongoose document. _id :", firstKittyDocument._id); // _id of document
    console.log("Mongoose document. name :", firstKittyDocument.name); // "Kitty 1"
    console.log("Mongoose document. color :", firstKittyDocument.color); // undefined
    // --> the document contains _id and other fields that we defined in the schema

    // we can call the method .toObject to get the plain object
    console.log("Using .toObject() method. _id :", firstKittyDocument.toObject()._id); // _id of document
    console.log("Using .toObject() method. name :", firstKittyDocument.toObject().name); // "Kitty 1"
    console.log("Using .toObject() method. color :", firstKittyDocument.toObject().color); // "red"
    // --> Using .toObject() method, we get all the fields we have in the dataObject

    // or we can use lean method to get the plain old javascript object
    const firstKittyPOJO = await Kitten.findOne({ name: "Kitty 1" }).lean();
    console.log("Using .lean() method. _id :", firstKittyPOJO._id);  // _id of document
    console.log("Using .lean() method. name :", firstKittyPOJO.name); // "Kitty 1"
    console.log("Using .lean() method. color :", firstKittyPOJO.color); //"red"
    // --> Using .lean() method, we get all the fields we have in the dataObject
}
like image 27
Đăng Khoa Đinh Avatar answered Nov 14 '22 02:11

Đăng Khoa Đinh


Well, Model.find() will Give you Array of objects found on DB, if you want to access directly to your object you can use Model.findOne()

OR => A quick Fix :

PatientOrderMigration.find({ mrn: orderitem.mrn, visituid: orderitem.visituid },function (err, orderDoc) {

    orderDoc = orderDoc[0];//Here is the Fix, you can comment this if you use findOne

    orderDoc.mrn = "New Value you want to update";

    orderDoc.save(function(err, result){
           console.log('err',err)
   })
}}
like image 4
lefdilia Avatar answered Nov 14 '22 02:11

lefdilia