msrumon
msrumon

Reputation: 1440

How to duplicate a document from one collection to another?

I have the following models I work with:

const { model, Schema } = require('mongoose');

const userSchema = new Schema({
  name: String,
  email: { type: String, unique: true },
  password: String,
});

const User = model('User', userSchema);

module.exports = { userSchema, User };

And

const { model, Schema } = require('mongoose');

const { userSchema } = require('./user');

const shopSchema = new Schema({
  name: String,
  address: String,
  contact: { type: String, unique: true },
  createdBy: userSchema,
  updatedBy: userSchema,
});

const Shop = model('Shop', shopSchema);

module.exports = { shopSchema, Shop };

Now the problem is: when I find a user from database and assigns it to createdBy and updatedBy fields, I get duplicate key error. Below is the code:

const { Shop } = require('./shop');
const { User } = require('./user');

const user = await User.findById(id);
const shop = new Shop({ createdBy: user, updatedBy: user });

And below is the error:

MongoError: E11000 duplicate key error collection: database.shops index: updatedBy.email dup key: { updatedBy.email: "[email protected]" }

Why do I get this error and how can I fix it?

Upvotes: 1

Views: 89

Answers (2)

msrumon
msrumon

Reputation: 1440

The issue was that I already had another document in the collection where createdAt.email and updatedAt.email matched with the document I wanted to insert. For example:

_id: ObjectId("...")
name: "..."
address: "..."
contact: "..."
createdBy: Object
    _id: ObjectId("...")
    email: "[email protected]"
updatedBy: Object
    _id: ObjectId("...")
    email: "[email protected]"

was already there, and I tried to add another document with those fields' values being equal.

But this shouldn't be an issue here, since I'm not assigning that document to it's parent, rather in a different collection as sub-document. So it shouldn't worry about duplicate key problem. Now I need to know if there is any way to tell MongoDB/Mongoose not to worry about this problem.

FIX:

Mongoose actually support index exclusion for nested sub-documents. Details can be found here. All you have to do is to pass a 2nd parameter to the Schema constructor, an object where you specify not to index sub-paths. Like so:

const shopSchema = new Schema(
  {
    //...
  },
  {
    excludeIndexes: true,
  }
);

Upvotes: 1

Mohammad Yaser Ahmadi
Mohammad Yaser Ahmadi

Reputation: 5051

you define email like this

 email: { type: String, unique: true }

when a field is unique, mongoose indices it, when a filed is index, there should be only one number in collection, so

The first way: you should delete unique: true from email after that drop collection to remove indexes completely or use command for deleting index

the second way: put the use model in one filed, in createdBy or updatedBy, when you put User in two fields in one collection, so created duplicate key

Upvotes: 0

Related Questions