To make MongoDB database manipulation easy, we can use the Mongoose NPM package to make working with MongoDB databases easier.
In this article, we’ll look at how to use Mongoose to manipulate our MongoDB database.
Populate Virtuals: The Count Option
We can add the count
option when we create a populate virtual to get the count of the number of children we retrieved.
For example, we can write:
async function run() {
const { createConnection, Types, Schema } = require('mongoose');
const db = createConnection('mongodb://localhost:27017/test');
const PersonSchema = new Schema({
name: String,
band: String
});
const BandSchema = new Schema({
name: String
}, { toJSON: { virtuals: true } });
BandSchema.virtual('numMembers', {
ref: 'Person',
localField: 'name',
foreignField: 'band',
count: true
});
const Person = db.model('Person', PersonSchema);
const Band = db.model('Band', BandSchema);
const person = new Person({ name: 'james', band: 'superband' });
await person.save();
const band = new Band({ name: 'superband' });
await band.save();
const doc = await Band.findOne({ name: 'superband' })
.populate('numMembers');
console.log(doc.numMembers);
}
run();
We created the PersonSchema
and BandSchema
schema objects.
We call the virtual
method on the BandSchema
schema with several options.
The ref
property is the model that the Band
model is referencing.
localField
is the field in the BandSchema
we want to join with PeronSchema
.
foreignField
is the field in the ForeignSchema
we want to join with PersonSchema
.
count
set to true
means that we get the count. numMembers
is the field name that we get the count from.
Then we save a Person
and Band
document with the same name.
Then we call populate
with the numMembers
field to get the number of members.
And finally, we get the numMembers
field from the retrieved result to get how many Person
children entries are in the Band
.
Populate in Middleware
We can add pre or post hooks to populate operations.
For example, we can write:
async function run() {
const { createConnection, Types, Schema } = require('mongoose');
const db = createConnection('mongodb://localhost:27017/test');
const PersonSchema = new Schema({
name: String,
band: String
});
const BandSchema = new Schema({
name: String
}, { toJSON: { virtuals: true } });
BandSchema.virtual('numMembers', {
ref: 'Person',
localField: 'name',
foreignField: 'band',
count: true
});
BandSchema.pre('find', function () {
this.populate('person');
});
BandSchema.post('find', async (docs) => {
for (const doc of docs) {
await doc.populate('person').execPopulate();
}
});
const Person = db.model('Person', PersonSchema);
const Band = db.model('Band', BandSchema);
const person = new Person({ name: 'james', band: 'superband' });
await person.save();
const band = new Band({ name: 'superband' });
await band.save();
const doc = await Band.findOne({ name: 'superband' })
.populate('numMembers');
console.log(doc.numMembers);
}
run();
to add the pre
and post
hooks to listen to the find
operation.
We should always call populate
with the given field to do the population.
Conclusion
We can add the count
property to add the count and also add pre and post hooks for find
operations with when we do the population.
One reply on “Using MongoDB with Mongoose — Populate Virtuals and Count”
What if i want always a less number of count