I have
Page.findById(pageId).then(page => { const pageId = page.id; .. });
My problem is that if no page id is given, it should just take the first available page given some conditions, which is done by
Page.findOne({}).then(page => { const pageId = page.id; .. });
but if no page is found, it should create a new page and use this, which is done with
Page.create({}).then(page => { const pageId = page.id; .. });
But how do I combine all this to as few lines as possible?
I have a lot of logic going on inside
page => { ... }
so I would very much like to do this smart, so I can avoid doing it like this
if (pageId) { Page.findById(pageId).then(page => { const pageId = page.id; .. }); } else { Page.findOne({}).then(page => { if (page) { const pageId = page.id; .. } else { Page.create({}).then(page => { const pageId = page.id; .. }); } }); }
I am thinking I maybe could assign a static to the schema with something like
pageSchema.statics.findOneOrCreate = function (condition, doc, callback) { const self = this; self.findOne(condition).then(callback).catch((err, result) => { self.create(doc).then(callback); }); };
Mongoose models have a create() function that is often used to create new documents. const User = mongoose.model('User', mongoose.Schema({ email: String })); const doc = await User.create({ email: '[email protected]' }); doc instanceof User; // true doc.email; // '[email protected]'
The find() function is used to find particular data from the MongoDB database. It takes 3 arguments and they are query (also known as a condition), query projection (used for mentioning which fields to include or exclude from the query), and the last argument is the general query options (like limit, skip, etc).
Mongoose by default does not create any collection for the model in the database until any documents are created. The createCollection() method is used to create a collection explicitly.
_id field is auto generated by Mongoose and gets attached to the Model, and at the time of saving/inserting the document into MongoDB, MongoDB will use that unique _id field which was generated by Mongoose.
As per the Mongoose docs:
As per previous SO answer
Model.findByIdAndUpdate()
"Finds a matching document, updates it according to the update arg, passing any options, and returns the found document (if any) to the callback."
In the options set upsert to true:
upsert: bool - creates the object if it doesn't exist. defaults to false.
Model.findByIdAndUpdate(id, { $set: { name: 'SOME_VALUE' }}, { upsert: true }, callback)
Related to Yosvel Quintero's answer which didn't work for me:
pageSchema.statics.findOneOrCreate = function findOneOrCreate(condition, callback) { const self = this self.findOne(condition, (err, result) => { return result ? callback(err, result) : self.create(condition, (err, result) => { return callback(err, result) }) }) }
And then use it like:
Page.findOneOrCreate({ key: 'value' }, (err, page) => { // ... code console.log(page) })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With