Mohi
Mohi

Reputation: 1808

MongoDB updating child document does not affect the original document and vise versa

I'm using mongoose and have these schema:

var mongoose = require('mongoose');
mongoose.connect(/*...*/)

const usersSchema = new Schema({
    email: String,
    name: String
})


const ordersSchema = new Schema({
    user: usersSchema, // <--- ref to usersSchema
    createdOn: Date,
    // ...
})

const UsersModel = mongoose.model('Users', usersSchema );
const OrdersModel = mongoose.model('Orders', ordersSchema );

The problem is when I insert an entity into Users collection and put that entity reference into the Orders.user field, It seems that Mongo does clone that object in the Orders collection.

// insert user:
var savedUser = await(new UsersModel({
    _id: mongoose.Types.ObjectId(),
    email: '[email protected]'
})).save();

// insert order with user reference:
var savedOrder = await(new OrdersModel({
    _id: mongoose.Types.ObjectId(),
    createdOn: new Date(),
    user: savedUser  // <--- ref to users
})).save();

Now I modify the user document:

// update original user:
var userDocToModify = await UsersModel.findById(savedUser._id);
userDocToModify.email = "[email protected]";
await userDocToModify.save();

Assertion will fail in the below line:

var orderDoc = await OrdersModel.findById(savedOrder._id);
assert(orderDoc.user.email == userDocToModify.email, 'email not changed in the orderDoc.user.email!');

Upvotes: 0

Views: 33

Answers (1)

Ana Lava
Ana Lava

Reputation: 787

Actually what you are doing here, is not referencing userSchema. You are embedding that schema into orders schema. If you want to reference user you should do as below:

const ordersSchema = new Schema({
    user: {type: mongoose.Schema.Types.ObjectId, ref: 'Users'}
    createdOn: Date,
    // ...
})

In this case you just store the user id in parent document. Now if you want to get orders and the user within it, you can either use mongoose population or $lookup in mongoose aggregation.

Upvotes: 1

Related Questions