I would like to only have a versioneditems
collection in MongoDB but I need to register both the VersionedItem
model and the ItemPatch
model because I need to create ItemPatch
es to populate a VersionedItem
.
There will be no separate ItemPatch
documents (they are embedded in a VersionedItem
). The code below is working except for the fact that an extra collection is created in MongoDB:
src/models/versionedItemFactory.js
const VersionedItemSchema = require('../schemas/VersionedItem');
module.exports = (db) => {
var VersionedItemModel = db.model('VersionedItem', VersionedItemSchema);
return VersionedItemModel;
};
src/models/itemPatchFactory.js
const ItemPatchSchema = require('../schemas/ItemPatch');
module.exports = (db) => {
var ItemPatchModel = db.model('ItemPatch', ItemPatchSchema);
return ItemPatchModel;
};
src/schemas/util/asPatch.js
var mongoose = require('mongoose');
module.exports = function _asPatch(schema) {
return new mongoose.Schema({
createdAt: { type: Date, default: Date.now },
jsonPatch: {
op: { type: String, default: 'add' },
path: { type: String, default: '' },
value: { type: schema }
}
});
};
src/schemas/Item.js
var mongoose = require('mongoose');
module.exports = new mongoose.Schema({
title: { type: String, index: true },
content: { type: String },
type: { type: String, default: 'txt' }
}, { _id: false });
src/schemas/ItemPatch.js
var asPatch = require('./util/asPatch');
var ItemSchema = require('./Item');
module.exports = asPatch(ItemSchema);
src/schemas/VersionedItem.js
var mongoose = require('mongoose');
var ItemPatchSchema = require('./ItemPatch');
module.exports = new mongoose.Schema({
createdAt: { type: Date, default: Date.now },
patches: [
{
createdAt: { type: Date, default: Date.now },
jsonPatch: { type: ItemPatchSchema }
}
]
});
Then registering like so:
db.once('open', function() {
require('./models/itemPatchFactory')(db);
require('./models/versionedItemFactory')(db);
});
I need to register the ItemPatch
model via itemPatchFactory
because I want to be able to populate a versioned item like so:
var itemPatch = new db.models.ItemPatch({
jsonPatch: {
op: 'add',
path: '',
value: {
title: 'This is a title',
content: 'This is content',
type: 'txt'
}
}
});
var itemPatch2 = new db.models.ItemPatch({
jsonPatch: {
value: {
title: 'This is a title 2',
content: 'This is content 2'
}
}
});
var versionedSomething = new db.models.VersionedItem();
versionedSomething.patches.push(itemPatch);
versionedSomething.patches.push(itemPatch2);
versionedSomething.save(function (err, result) {
if (err) throw err;
console.log('result:', result);
});
This successfully creates the versioned item with the 2 patches in it, but an (empty) itempatches
collection is created in MongoDB and I'd like to avoid that.
Its not possible anymore. You can use Mongoose with the collections that have schema and the node driver or another mongo module for those schemaless ones.
Mongoose never create any collection until you will save/create any document.
To use Mongoose without defining a schema, we can define a field with the Mixed data type. const Any = new Schema({ any: Schema. Types. Mixed });
You can't create a Model
without a corresponding collection, but I don't think you actually need to in order to do what you want.
You can simply create a javascript object for the child and push it to the parent collection. See this snippet from the Mongoose docs (https://mongoosejs.com/docs/subdocs.html)
var Parent = mongoose.model('Parent');
var parent = new Parent;
// create a comment
parent.children.push({ name: 'Liesl' });
var subdoc = parent.children[0];
console.log(subdoc) // { _id: '501d86090d371bab2c0341c5', name: 'Liesl' }
subdoc.isNew; // true
parent.save(function (err) {
if (err) return handleError(err)
console.log('Success!');
});
You can create a Schema
for the subdocument, however. That will let you enforce the structure when reading/writing from the parent collection:
var childSchema = new Schema({ name: 'string' });
var parentSchema = new Schema({
// Array of subdocuments
children: [childSchema],
// Single nested subdocuments. Caveat: single nested subdocs only work
// in mongoose >= 4.2.0
child: childSchema
});
You can use the mongoose Schema options - autoCreate: false, autoIndex: false to not create the mongodb collection.
[1] https://mongoosejs.com/docs/guide.html#autoIndex
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