Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge two objects in mongoose

I have two models in user.js and userProfile.js of mongoose, where I want to get documents using a join query but I have not take ref in user schema so I have code as below:

user.js

var userSchema = new Schema({
     nick_name:{type:String},
     email: {type: String},
     password: {type: String},
    is_active:{type:String,enum:['1','0'],default:"1"},
},{ collection: 'user'});

userProfile.js

var userProfileSchema = new Schema({
    user_id:{type:Schema.Types.ObjectId, ref:'User'},
    first_name:{type:String},
    last_name:{type:String},
    address:{type:String},
    country:{type:String},
    state:{type:String},
    city:{type:String},
    gender:{type:String,enum:['m','f','o'],default:"m"},
    is_active:{type:String,enum:['1','0'],default:"1"},
},{ collection: 'userProfile'});

server.js

app.get('/api/userLists', function(req, res) {
    User.find({},"nick_name email",function(err, user) {
        if(err) {
            res.json(err);
        } else {
            var userIds = user.map(function(obj){
               return obj._id;
            });

            UserProfile.find({user_id:{$in:userIds}},function(err,userProfiles){
                if(err){
                    res.json(userProfiles);
                    console.log(userProfiles);
                }else{

                    ---------------------------------
                    -What to do here, I have no idea.-
                    ---------------------------------

                    res.json(user);
                }
            });

        }
    });

});

expected output as follows

{
 "nick_name"   : "laxman",
 "email"       : "[email protected]",
 "first_name"  : "my first name",
 "last_name"   : "my last name",
 "address"     : "my address",
 "country"     : "my country",
 "state"       : "my state",
 "city"        : "my city",
 "gender"      : "m",
}

**OR**

{
 "nick_name"   : "laxman",
 "email"       : "[email protected]",
 "profile" :{
        "first_name"  : "my first name",
        "last_name"   : "my last name",
        "address"     : "my address",
        "country"     : "my country",
        "state"       : "my state",
        "city"        : "my city",
        "gender"      : "m",
   }
}

dependencies

"express"  => "version": "4.7.4",
"mongoose" => "version": "4.4.5",
"mongodb"  => "version": "2.4.9",
"OS"  => "ubuntu 14.04 lts 32bit",
like image 718
laxman Avatar asked Dec 03 '25 13:12

laxman


1 Answers

Population would be ideal in your case. From the docs:

Population is the process of automatically replacing the specified paths in the document with document(s) from other collection(s).

Population will seamlessly help you bring data from the Profile collection into your User model. For example, to get the second output in the json form

{
    "nick_name": "laxman",
    "email": "[email protected]",
    "profile": {
        "first_name"  : "my first name",
        "last_name"   : "my last name",
        "address"     : "my address",
        "country"     : "my country",
        "state"       : "my state",
        "city"        : "my city",
        "gender"      : "m",
    }
}

consider the following example with the approach you can take. Change your User schema to

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var userSchema = new Schema({
    nick_name: { type: String },
    email: { type: String },
    password: { type: String },
    profile: { type: Schema.Types.ObjectId, ref: 'UserProfile' }
},{ collection: 'user'});

module.exports = mongoose.model('User', userSchema);

In your user schema definition, you add the primary surrogate key to a user profile, called ObjectId, referenced as _id in the data to get the populate functionality. This will be the key used to refer to documents in the UserProfile collection.

Reading the data

This is where Mongoose population displayes how very straightforward, easy and fast it is to makes reads of documents through its populate() function. So for instance, to show the referenced profile on a user, call the populate() method with the name of that field in a string as a parameter e.g.

app.get('/api/userLists', function(req, res) {
    User.find({}, "nick_name email")
        .populate("profile")
        .exec(function(err, users) {
            if(err) {
                res.json(err);
            } else {
                res.json(users)
            }
        });

Writing data

When you save data for the user model, you will also need to save the references to the profile. For instance, when a new User is created, you'll need the UserProfile _id reference saved as the profile field:

var user = new User();
var profileId = "54b5659536cd5250a3a93bd3"; // <-- user profile id, for example.
user.nick_name = req.body.name;
user.email = req.body.email;
user.password = encrypt(req.body.password, user.nick_name);
user.profile = profileId; 

user.save(function(err) {
    if (err)
        res.send(err);
    res.json({ message: 'user created!' });
});
like image 163
chridam Avatar answered Dec 05 '25 04:12

chridam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!