1

I am developing a NodeJS application with Express and MongoDB. My objects were not getting saved to the database, so I dug deeper and I found that the target collection was not created if I used:

const PersonSchema = new Schema({
  firstName: String,
});

and the collection was created if I used

const PersonSchema = new Schema({
  firstName: { type: String, unique: true},
});

In either case, the full model in server/models/person.js is:

'use strict';

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

// Use native promises.
mongoose.Promise = global.Promise;

// Define the Person schema.
const PersonSchema = new Schema({
  // ...
});

const Person = mongoose.model('Person', PersonSchema);

module.exports = Person;

I have MongoDB 4.2.3 (with db.version() in the mongo shell), npm 6.14.4, mongoose 5.7.5, and npm mongodb 3.3.2 (with npm list | grep mongodb).

Why does MongoDB require a unique field in addition to _id to create a collection?

miguelmorin
  • 5,025
  • 4
  • 29
  • 64
  • Hi there! I just tried duplicating this on my end with near the same version of mongoose and MongoDB, it worked fine, the documents were created without the unique property on the `firstName` field in the schema. I don't think the reason your objects were not saved in the DB is because of the absence of the unique property. – Tunmee Apr 01 '20 at 10:38
  • 1
    Also, the reason the collection was not created without the unique property is that mongoose(or MongoDB itself) won't create a collection until you insert data into the collection. By adding the unique property, MongoDB would have to create an index document for that property in the collection consequently adding data to the collection and this is why it seems that the collection was created only after adding the unique property. So while the `db..find({})` might return nothing, `db..getIndexes()` would give you something. – Tunmee Apr 01 '20 at 10:39
  • @Tunmee Indeed, that's correct: without `unique: true`, I see no collection but `db..getIndexes()` returns an object with details; also creating a document in the collection creates the collection. Could you write an answer? – miguelmorin Apr 02 '20 at 07:28
  • Sure, I can do that. – Tunmee Apr 02 '20 at 09:09

1 Answers1

1

I just tried replicating the scenario you described above on my end with near the same version of mongoose and MongoDB, it worked fine, documents were created(and saved) without the unique property on the firstName field in the schema. I don't think the reason your objects were not saved in the DB is because of the absence of the unique property.

Also, the reason the collection was not created without the unique property is that mongoose(or MongoDB itself) won't create a collection until you insert data into the collection. By adding the unique property, MongoDB would have to create an index document for that property in the collection consequently adding data to the collection and this is why it seems that the collection was created only after adding the unique property. So while the db.<collectionName>.find({}) might return nothing, db.<collectionName>.getIndexes() would give you something.

Tunmee
  • 2,483
  • 1
  • 7
  • 13