mongoosejs / mongoose-lean-virtuals Goto Github PK
View Code? Open in Web Editor NEWAttach virtuals to the results of mongoose lean() queries
License: Apache License 2.0
Attach virtuals to the results of mongoose lean() queries
License: Apache License 2.0
When using with
import mongooseLeanVirtuals from "mongoose-lean-virtuals";
it gives the same error as the mongoose-lean-getters plugin: mongoosejs/mongoose-lean-getters#11
/usr/current/app/node_modules/mongoose/lib/schema.js:1406
throw new Error('First param to `schema.plugin()` must be a function, '
Is there some other way to use this plugin?
Hello; is there any particular order in which I must call lean()?
The following did not work:
Address
.find()
.lean({ virtuals: true })
.or([{
'name': text
}, {
'address': text
}])
.and([{
'addressType': type.toString()
}])
.populate('country addressType')
.exec(function (err, addresses) {
debugger;
if (err)
res.status(500).send(err);
else
res.status(200).send(addresses);
});
Hi,
If get a document with discriminator array field from database with [email protected], an error will occur even if don't have any virtual fields.
Below is the test code to reproduce the problem:
const mongoose = require('mongoose');
const mongooseLeanVirtuals = require('mongoose-lean-virtuals');
const ObjectId = mongoose.Types.ObjectId;
const Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true, useUnifiedTopology: true });
const testSchema = new Schema({
title: String,
values: {
type: [new Schema({
fieldId: { type: Schema.Types.ObjectId, required: true },
value: Schema.Types.Mixed,
})]
},
});
testSchema.path('values').discriminator('String', new Schema({
fieldId: { type: Schema.Types.ObjectId, required: true },
value: {
type: String,
},
}));
testSchema.path('values').discriminator('Multi-String', new Schema({
fieldId: { type: Schema.Types.ObjectId, required: true },
value: {
type: [String],
required: true
},
}));
testSchema.plugin(mongooseLeanVirtuals);
const testModel = mongoose.model('test', testSchema);
describe('test', () => {
before('Clear collection and add sample document', async () => {
await testModel.deleteMany({});
await new testModel({
title: 'test',
values: [{
fieldId: new ObjectId(),
value: 'abc',
__t: 'String'
},
{
fieldId: new ObjectId(),
value: [
'abc',
'sfadsf',
'bvbd'
],
__t: 'Multi-String'
}]
}).save();
});
after('DB disconnect', async () => {
await mongoose.disconnect();
});
it('Can it run without error?', async () => {
const testDoc = await testModel.findOne({ title: 'test' }).lean({ virtuals: true });
console.log(JSON.stringify(testDoc));
});
});
And the error message is:
$ mocha index.js
test
1) Can it run without error?
0 passing (66ms)
1 failing
1) test
Can it run without error?:
TypeError: Cannot read property 'Multi-String' of undefined
at findCorrectDiscriminator (node_modules/mongoose-lean-virtuals/index.js:127:52)
at Array.find (<anonymous>)
at attachVirtualsToDoc (node_modules/mongoose-lean-virtuals/index.js:125:40)
at applyVirtualsToResult (node_modules/mongoose-lean-virtuals/index.js:78:7)
at model.Query.attachVirtuals (node_modules/mongoose-lean-virtuals/index.js:71:10)
at applyVirtualsToChildren (node_modules/mongoose-lean-virtuals/index.js:111:20)
at model.Query.attachVirtuals (node_modules/mongoose-lean-virtuals/index.js:70:3)
at model.Query.<anonymous> (node_modules/mongoose-lean-virtuals/index.js:43:22)
at next (node_modules/kareem/index.js:198:31)
at Kareem.execPost (node_modules/kareem/index.js:217:3)
at _cb (node_modules/kareem/index.js:307:15)
at /Users/bit072/repo/mongoose-lean-virtuals-discriminator-error/node_modules/mongoose/lib/query.js:4445:12
at _completeOneLean (node_modules/mongoose/lib/query.js:3635:10)
at model.Query.Query._completeOne (node_modules/mongoose/lib/query.js:2101:7)
at Immediate.<anonymous> (node_modules/mongoose/lib/query.js:2146:10)
at Immediate.<anonymous> (node_modules/mquery/lib/utils.js:116:16)
at processImmediate (internal/timers.js:456:21)
nodejs: 12.18.0
mongodb: 4.2.7
mongoose: 5.10.1
mongoose-lean-virtuals: 0.6.8
mocha: 8.1.2
Do you want to request a feature or report a bug?
I would like to report a bug in that library.
Steps to reproduce.
'use strict'
import assert from 'assert'
import mongoose from 'mongoose'
(async () => {
try {
await mongoose.connect('mongodb://localhost:27017/test', {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false
})
const plugin = require('mongoose-lean-virtuals')
const T1 = new mongoose.Schema({ t11: String }, { _id: false })
T1.virtual('t12').get(() => 't12')
T1.plugin(plugin)
const T2 = new mongoose.Schema({ t1: T1, t2: String })
T2.virtual('t21').get(() => 't21')
T2.plugin(plugin)
const MT2 = mongoose.model('MT2', T2)
const reps = new MT2({ t1: { t11: 't11' }, t2: 't2' })
await reps.save()
const received = await MT2.findById(reps._id).lean({ virtuals: true }).exec()
const expected = {
_id: reps._id,
id: reps._id.toString(),
t1: { t11: 't11', t12: 't12' /* virtual */ },
t2: 't2',
t21: 't21' /* virtual */,
__v:0
}
/* the following assertion fails */
assert.deepStrictEqual(received, expected)
process.exit(0)
} catch (e) {
console.info(e)
process.exit(-1)
}
})()
Expected behaviour
When passing { virtuals: true }
, I would expect that the plugin also applies this to sub-schemas, so that my above virtual field t2.t21
is populated. I would even suggest adding another option, say { deep: true }
either for the lean
(e.g. lean({ virtuals: true, deep: true })
) or suggest a plugin option proper to the schema (e.g. schema.plugin(require('mongoose-lean-virtuals'), { deep: true })
). We may even do both so that the option given to the lean()
method overrides the one given to the plugin, although not sure whether it is possible with the current framework.
The problem arises from there https://github.com/vkarpov15/mongoose-lean-virtuals/blob/f39b0a66a26432609124f47247400b7b30caca46/index.js#L115-L125 As you can see, when virtuals
is set to true
, then it does not consider the keys of schema.virtuals
.
EDIT: I removed my fix which is not an entirely correct fix. I will need to investigate more but this issue remains as is, I think.
Versions
Node.js: 10.21.0
Mongoose: 5.11.4
mongoose-lean-virtuals: 0.7.5
MongoDB: 4.4.2
The title seems complicated, so is the bug. This specific case does not work for me.
I have a virtual populated field (which is referenced to same model), and I have a virtual field that simply returns a string. The virtual field works on the parent document, but does not work on the child document. I am including the full working script and the current and expected output below.
Gist:
https://gist.github.com/sulaysumaria/2ab2f55363cc56b231f2deaefd96c611
Current output:
{
id: 'XRd8AEsA0kt9Lqcp6qkD57tf',
name: 'User two',
avatarId: 'XRd8AEsA0kt9Lqcp6qkD57tf',
referencedById: 'JmGvkmbTyPRIdzjny5r5i08k',
avatar: { id: 'XRd8AEsA0kt9Lqcp6qkD57tf', fileName: 'File one' },
referencedBy: {
id: 'JmGvkmbTyPRIdzjny5r5i08k',
name: 'User one',
avatarId: 'XRd8AEsA0kt9Lqcp6qkD57tf',
avatar: { id: 'XRd8AEsA0kt9Lqcp6qkD57tf', fileName: 'File one' }
},
virtualField: 'some virtual id'
}
Expected output:
{
id: 'XRd8AEsA0kt9Lqcp6qkD57tf',
name: 'User two',
avatarId: 'XRd8AEsA0kt9Lqcp6qkD57tf',
referencedById: 'JmGvkmbTyPRIdzjny5r5i08k',
avatar: { id: 'XRd8AEsA0kt9Lqcp6qkD57tf', fileName: 'File one' },
referencedBy: {
id: 'JmGvkmbTyPRIdzjny5r5i08k',
name: 'User one',
avatarId: 'XRd8AEsA0kt9Lqcp6qkD57tf',
avatar: { id: 'XRd8AEsA0kt9Lqcp6qkD57tf', fileName: 'File one' },
virtualField: 'some virtual id' // <----- This field should be present but is not.
},
virtualField: 'some virtual id'
}
Versions:
mongoose - 6.1.9
mongoose-lean-virtuals - 0.9.0
I found this issue related to the bug I am facing, but the solution mentioned there does not work. #50
I have a very nested structure and need have the following getter for one of my object:
const getParent = (doc: Document | any): any => {
return doc instanceof Document
? (doc as Types.Subdocument).parent()
: mongooseLeanVirtuals.parent(doc);
};
MySchema.virtual("attr").get(function (this: BaseValuesType): number | undefined {
const parent = getParent(this);
const parentOfParent = getParent(parent);
// do something with parentOfParent
};
This works without a problem doing .toObject()
on a constructed instance but it fails with parentOfParent
being undefined
when using lean({ virtuals: true })
on a query.
Hi !
With mongoose 5.12.2 and mongoose-lean-virtuals 0.7.6, just found that the next query only lean the root _id value :
Project.find(match)
.select('_id name')
.populate('company', '_id name')
.lean({ virtuals: ['id'] }); // we only need the id virtual
// Return :
"{
"_id": "5cade6a33c27940010c01de2",
"company": {
"_id": "5cadc7773c27940010c00298",
"name": "SOME COMP"
},
"name": "A PROJECT",
"id": "5cade6a33c27940010c01de2"
}"
result.company haven't any "id" property.
From the past, with mongoose 5.9.1 and mongoose-lean-virtuals 0.5.0, the same query return :
"{
"_id": "5cade6a33c27940010c01de2",
"company": {
"_id": "5cadc7773c27940010c00298",
"name": "SOME COMP",
"id": "5cadc7773c27940010c00298"
},
"name": "A PROJECT",
"id": "5cade6a33c27940010c01de2"
}"
Virtual worked fine with subdocument.
However, It work well using .lean({ virtuals: true });
.
But we have some virtuals that we dont want to return everytime, and deleting them from each document/subdocument is not suitable.
Is it intended ?
Bug
The virtuals of sub-documents in nested arrays aren't attached to the result when I specify the virtual paths { virtuals: [...] }
. It works fine when I lean the query with { virtuals: true }
import mongoose from "mongoose";
import { mongooseLeanVirtuals } from "mongoose-lean-virtuals";
mongoose.plugin(mongooseLeanVirtuals);
const NameSchema = new mongoose.Schema({
first: { type: String, required: true },
last: String,
});
NameSchema.virtual("full").get(function () {
return `${this.first} ${this.last ?? ""}`.trim();
});
const ChildSchema = new mongoose.Schema({
age: { type: Number, required: true },
name: { type: NameSchema, required: true },
}, { _id: false });
const ParentModel = mongoose.model(
"Parent",
new mongoose.Schema({
name: { type: NameSchema, required: true },
child: ChildSchema,
nested: new mongoose.Schema({
children: [ChildSchema],
}),
})
);
async function run() {
await mongoose.connect("...");
await ParentModel.create({
name: { first: "Homer", last: "Simpson" },
child: { age: 10, name: { first: "Bart", last: "Simpson" } },
nested: {
children: [
{ age: 6, name: { first: "Lisa", last: "Simpson" } },
{ age: 3, name: { first: "Baby" } },
],
},
});
const result = await ParentModel.find({})
.populate("child")
.populate("nested.children")
.lean({
virtuals: ["name.full", "child.name.full", "children.name.full"],
});
assert.equal(result.name.full, "Homer Simpson"); // Pass
assert.equal(result.child.name.full, "Bart Simpson"); // Pass
assert.equal(result.children[0].name.full, "Lisa Simpson"); // Fail
assert.equal(result.children[1].name.full, "Baby"); // Fail
}
run().catch(console.error)
For the virtuals of the sub-documents in nested arrays to be attached.
Package | Version |
---|---|
mongoose | 6.4.3 |
mongoose-lean-getters | N/A |
Node.js | 18.6.0 |
When i have virtual on discriminator it doesn't return the virtuals on the result.
for example:
let's assume we have BaseModel
.
The DerivedModel
has virtual method called foo.
If we do DerivedModel.find({}).lean({virtuals: true})
we will not get the foo property
If I have a child schema nested within the main schema, the virtual defined on the child schema doesnt come.
eg.
const mongoose = require('mongoose');
const leanVirtualPlugin = require('mongoose-lean-virtuals');
const childSchema = new mongoose.Schema({
name: {
type: String
}
}, {
timestamps: true,
toObject: {
virtuals: true
},
toJSON: {
virtuals: true
}
});
childSchema.virtual('something').get(function() {
return 'something';
});
const mainSchema = new mongoose.Schema({
name: {
type: String
},
children: [childSchema]
}, {
toObject: {
virtuals: true
},
toJSON: {
virtuals: true
}
});
mainSchema.virtual('main').get(function() {
return 'main';
});
mainSchema.virtual('children.someOtherThing').get(function() {
return 'someOtherThing';
});
mainSchema.set('collection', 'test');
mainSchema.plugin(leanVirtualPlugin);
const TestModel = mongoose.model('test', mainSchema);
Now TestModel.find().lean({virtuals:true}).exec() , gives me the 'main' virtual, also 'someOtherThing' virtual as a key of children (not for each array item). But it doesnt give me the child virtual 'something' on each element of the children array. Like -
_id: 5c8955801b7d3179990b2150, name: 'hello', children: [ { _id: 5c8955801b7d3179990b2152, name: 'child1', }, { _id: 5c8955801b7d3179990b2151, name: 'child2', }, someOtherThing: 'someOtherThing' ], main: 'main',
When i use lean with virtuals: true i would expect the getter will be also reflected in the result.
I couldn't find anything in the documentation so i am not sure how i can tackle this issue.
I am using Decimal128 type and i need to get it as real double to avoid conversions across the code.
Any help will be appreciated.
Thanks
Plugin version: 0.7.6
Mongoose version: 5.12.3
Schema:
var variationSchema = mongoose.Schema({
variation: {type: mongoose.Schema.Types.ObjectId, ref: 'VariationType'},
optionsAvailable:
[{
label: String,
SKUFragment: String,
sortOrder: Number
}]
});
var stockSchema = mongoose.Schema({
map: [Number],
SKU: {type: String, index: true},
amount: Number,
price: Number,
images: {
truncatedForBrevity: String
},
display: {type:Boolean, default: true}
}, schemaOptions);
var MainSchema = mongoose.Schema({
name: String,
categories: [{type: mongoose.Types.ObjectId, ref: 'StoreCategory', index: true}],
onSale: {type: Boolean, default: true},
availableOnline: {type: Boolean, default: true},
SKUPrefix: String,
basePrice: Number,
description: String,
variations: [variationSchema],
images: { truncatedForBrevity: String },
stock: [stockSchema],
deleted: {type: Boolean, default: false},
}, schemaOptions);
stockSchema.virtual('label').get(function() {
let parent;
if (this instanceof mongoose.Document) {
parent = this.parent();
} else {
parent = mongooseLeanVirtuals.parent(this);
}
const variations = parent.variations;
let labelArray = [];
this.map.forEach(function (v, index) {
let variation = variations[index];
let type = variation.optionsAvailable[v];
labelArray.push(type.label);
});
return labelArray.join(', ');
});
stockSchema.label
is a virtual getter that's supposed to iterate through its map property and identify it against the values found its parent's (MainSchema
) property `variation' and assemble a label.
With a valid sample JSON object using the above schema looking like this (I removed most of the irrelevant properties):
{
"_id": "60673d22b68709e3a4393e75",
"variations": [
{
"_id": "60673d22b68709e3a4393e76",
"variation": {
"_id": "5fda879333124842b57bf2df",
"label": "Size",
"isSize": true
},
"optionsAvailable": [
{
"_id": "60673d22b68709e3a4393e77",
"label": "Extra Small",
"SKUFragment": "XS",
"sortOrder": 0,
"id": "60673d22b68709e3a4393e77"
},
{
"_id": "60673d22b68709e3a4393e78",
"label": "Small",
"SKUFragment": "SM",
"sortOrder": 1,
"id": "60673d22b68709e3a4393e78"
},
],
"id": "60673d22b68709e3a4393e76"
},
{
"_id": "60673d22b68709e3a4393e7c",
"variation": {
"_id": "5fda879333124842b57bf2e0",
"label": "Color"
},
"optionsAvailable": [
{
"_id": "60673d22b68709e3a4393e7d",
"label": "Blue",
"SKUFragment": "BLU",
"sortOrder": 0,
"id": "60673d22b68709e3a4393e7d"
},
{
"_id": "60673d22b68709e3a4393e7e",
"label": "Black",
"SKUFragment": "BLK",
"sortOrder": 1,
"id": "60673d22b68709e3a4393e7e"
}
],
"id": "60673d22b68709e3a4393e7c"
}
],
"stock": [
{
"map": [0, 0],
"display": true,
"_id": "6075017f1824dc2460a3f481",
"amount": 5,
"price": 800,
"SKU": "BYF2L-XS-BLU",
"images": {
"main": "s3:///store/uploads/BYF2L/BYF2L-LG-BLU/main.jpg",
},
"label": "Extra Small, Blue",
"id": "6075017f1824dc2460a3f481"
}
],
"name": "Mongoose Tee",
"description": "This awesome t-shirt shows that you love mongodb and mongoose!",
}
Using .findOne().lean({virtuals: true})
the .label
virtual getter works fine. However, with .find().lean({virtuals: true})
it fails because in stockSchema.label
the call to mongooseLeanVirtuals.parent(this)
returns undefined.
Stepping through the applyVirtualsToResult()
call in the plugin:
if (parent != null && res[i] != null && typeof res[i] === 'object') {
documentParentsMap.set(res[i], parent);
}
Using find()
: Both res[i]
and parent
are each an array of arrays of objects. (Fail case)
Using findOne()
: Both res[i]
and parent
are each arrays of objects. (Success case)
Hello,
When my documents have subdocuments (lets call it subs
) the function attachVirtuals is called twice, once for each set of documents. By defaults, the virtuals to apply are taken from the (sub)schema and then everything works. However, this doesn't allow me to specify which virtuals I would like to include. When I specify an array of virtuals explicitly (lets use [rootVirtual]
) then I would expect rootVirtual
to be set on the root documents and not on the set of subdocuments as the virtual doesn't start with subs.
, instead the virtual is being applied on both set of documents. This results in an error as the subdocument schema doesn't have this virtual.
Any way to solve this issue?
Best
Would be a big benefit to be able to default adding virtuals to true. This way only the model has to be updated and all existing usage of .lean() will work with the new virtual. Currently, all usages have to be updated to include {virtuals: true}
.
Hello,
In our codebase we were doing
ourModel.find(OUR_QUERY)
.lean({ virtuals: true })
.cursor()
.eachAsync(p => {
// p is not a POJO but a Model instance
// w/ save, update... methods
});
Still as the comment in the callback suggest, p
is not a POJO (and it should be as stated here).
This is not a bug related to this plugin since mongoose itselft checks the explicit true
value of the lean options before hitting the eachAsync
callback (here).
Should the verification done by mongoose check the truthyness of the lean option instead of the explicit true
value ?
Or should this be marked as the expected behavior in the documentation of this plugin ?
Also how to get the virtuals in the async w/ the lean
🤔 (dropping the lean
and using .toObject()
works, but it makes no use of the lean
feature...)
In any case, I'ld be glad to help :)
Thank you.
edit: checking the truthyness in mongoose would not help because the .cursor
method does not trigger post find hooks, which this plugin relies on.
I've been using this library for a while with just {virtuals: true} and found it really helpful but I need to limit the number of virtuals being returned so attempted to replace true
with an array of names. It almost works but I was getting an error when using this in a query that populates referenced docs. The line below fails because applyGetters is called against an undefined value:
cur[sp[sp.length - 1]] = schema.virtuals[virtual].applyGetters(cur[sp[sp.length - 1]], doc);
Simply testing to see if schema.virtuals[virtual]
exists before this line seems to have worked. One concern I have is that the virtuals provided in the list are not specific to any particular schema, The code will give you virtuals from every sub-schema where a virtual matches the name. That is fine once understood but it would be really nice to be able to be more specific. For example if you have a student record with a contact record you might want to specify virtuals as ['currentStatus', 'contact.fullName']
to get the first from the top level schema and the second from the specific child schema.
mongoose-lean-methods seen to be deprecated.
could it support lean virtual method?
Virtual Property:
schema.virtual('startDateF').get(function() {
return moment(this.startDate).format(DATE_FORMAT);
});
Execution:
Subscription.find(query).lean({virtuals: true}).exec();
Output does not include a startDateF
virtual property
Note: it works in 0.3.2
I had a piece of code that did
let query = Model.find({ foo: 'bar' }).setOptions( opts ).lean({ virtuals: true })
let cursor = query.cursor()
//...
let doc = cursor.next()
And in 4.x it worked with virtuals populated. Not so in mongoose 5.x.
Thanks!
Currently published version is 0.5.2 on npm https://www.npmjs.com/package/@types/mongoose-lean-virtuals. This causes type disrepancies. Please publish a new version whenever it's convenient.
The following code is not working
const mongoose = require('mongoose');
const mongooseLeanVirtuals = require('mongoose-lean-virtuals');
const { paginate } = require('mongoose-paginate-v2');
//const opts = { toJSON: { virtuals: true } };
const post = mongoose.Schema({
user_id: String,
title: String,
content: String,
media: {
default: "",
type: String
},
tag: [
String
],
created_time: {
default: Date.now,
type: Date
},
reactions: [
{
user_id: String,
reaction_type: String
}
],
permission: {
type: String,
default: "open"
}
})
const commentSchema = mongoose.Schema({
user_id: String,
content: String,
media: {
type: String,
default:""
},
reactions: [
{
user_id: String,
reaction_type: String
}
],
created_time: {
default: Date.now,
type: Date
},
})
commentSchema.add({
comments: [
{
commentSchema
}
],
})
post.add({
comments: [
commentSchema
]
})
commentSchema.virtual('comment_id').get(function () {
return this._id;
});
commentSchema.plugin(mongooseLeanVirtuals);
post.virtual('post_id').get(function () {
return this._id;
});
post.plugin(mongooseLeanVirtuals);
module.exports = mongoose.model('post', post);
I'm having the same exact issue as #40, but I wasn't able to find any documentation/example on how the parent() function is supposed to be used.
I would greatly appreciate it if you could point me to an example of how to use it.
Thanks
We have a virtual on a child schema that needs visibility to the parent document.
ChildSchema.virtual('hasAThing').get(function () {
const parent = this.parent(); // fails!
return parent.arrayOfThings.some(
(thing) => thing.status === 'valid' and thing.items.includes(this._id)
);
});
ParentSchema = new Schema(
{
_id: { type: ObjectId, required: true },
arrayOfThings: [ChildSchema]
});
ParentSchema.plugin(mongooseLeanVirtuals);
ParentSchema.set('toJSON', { virtuals: true });
ParentSchema.set('toObject', { virtuals: true });
I was hoping (expecting?) that the ability to see .parent() (or .ownerDocument()) from Mongoose would work here as documented in other places e.g. https://mongoosejs.com/docs/subdocs.html#subdoc-parents
But these are undefined. Should they be? Is there a way of accessing the parent document as part of leanvirtuals?
Stack trace that happens:
Object. (/myProject/src/my.model.js:101:20)
at VirtualType.applyGetters (/myProject/src/node_modules/mongoose/lib/virtualtype.js:142:25)
at attachVirtualsToDoc (/myProject/src/node_modules/mongoose-lean-virtuals/index.js:148:55)
at attachVirtualsToDoc (/myProject/src/node_modules/mongoose-lean-virtuals/index.js:119:7)
at applyVirtualsToResult (/myProject/src/node_modules/mongoose-lean-virtuals/index.js:78:7)
at model.Query.attachVirtuals (/myProject/src/node_modules/mongoose-lean-virtuals/index.js:71:10)
at applyVirtualsToChildren (/myProject/src/node_modules/mongoose-lean-virtuals/index.js:111:20)
at model.Query.attachVirtuals (/myProject/src/node_modules/mongoose-lean-virtuals/index.js:70:3)
at model.Query. (/myProject/src/node_modules/mongoose-lean-virtuals/index.js:43:22)
at /myProject/src/node_modules/mongoose-lean-virtuals/index.js:11:12
(the error occurs on the line where I attempt to call .parent()
or .ownerDocument()
)
How do I reference the parent document from a child virtual when using this library?
Mongoose ver 5.10.2
Mongoose-lean-virtuals ver 0.6.9
Hello, and thank you for a great plugin
I've encountered an issue, when I am using cursor
Few code of example (migrations, so I do not care about performance)
let db = await require('../../util/db').connect()
console.log('Started ...')
try {
const cursor = DocModel.find().cursor()
for (let doc = await cursor.next(); doc; doc = await cursor.next()) {
console.log('Processing document...', doc._id)
try {
await doc.save() // trigger hooks
} catch (err) {
console.log('Could not execute:', err)
}
}
} catch (error) {
console.error(error)
}
console.log('Finished ...')
await db.disconnect()
And in model:
const DocModelSchema = new mongoose.Schema({
// ...
})
DocModelSchema.plugin(mongoosePaginate)
module.exports = mongoose.model('DocModel', DocModelSchema)
When I am commenting DocModelSchema.plugin(mongoosePaginate)
- everything works as expected
We have the following virtual defined in our schema:
AnnotationTypeSchema.virtual('instances', {
ref: AnnotationType.name,
localField: 'classToAnnotate',
foreignField: 'classToAnnotate',
match: { textField: { $exists: true } },
}).get((instances: BaseAnnotationType[]) => instances.map(instance => instance.textField));
And we're trying to execute the following query:
const items = await this.annotationTypeModel
.find(searchFilter)
.limit(filter.limit)
.skip(filter.limit * (filter.page - 1))
.sort({ title: 1 })
.populate('instances')
.lean({ virtuals: true, getters: true })
.exec();
But we get the error, that the instances is undefined and therefore the map function cannot be executed.
Don't know if the intended behavior of the Plugin should cover such cases.
It seems that v0.4.0 has broken population of virtuals in child schemas when doing a find
operation. To demonstrate take the 'with nested schemas' unit test and replace the findOne()
operation with a find({})
operation like so:
it('with nested schemas (gh-20)', function() {
const schema = new mongoose.Schema({ name: String });
schema.virtual('lower').get(function() {
return this.name.toLowerCase();
});
const parentSchema = new mongoose.Schema({
nested: schema,
arr: [schema]
});
parentSchema.plugin(mongooseLeanVirtuals);
const Model = mongoose.model('gh20', parentSchema);
return co(function*() {
yield Model.create({
nested: { name: 'FOO' },
arr: [{ name: 'BAR' }, { name: 'BAZ' }]
});
const doc = (yield Model.find({}).lean({ virtuals: true }))[0];
assert.equal(doc.nested.lower, 'foo');
assert.equal(doc.arr[0].lower, 'bar');
assert.equal(doc.arr[1].lower, 'baz');
});
});
If you run npm test
you will get the following stack:
TypeError: Cannot read property 'toLowerCase' of undefined
at Array.<anonymous> (test/index.test.js:89:24)
at VirtualType.applyGetters (node_modules/mongoose/lib/virtualtype.js:118:25)
at attachVirtualsToDoc (index.js:80:55)
at model.Query.attachVirtuals (index.js:47:9)
at model.Query.attachVirtuals (index.js:61:22)
at model.Query.<anonymous> (index.js:20:20)
at next (node_modules/kareem/index.js:198:31)
at Kareem.execPost (node_modules/kareem/index.js:217:3)
at _cb (node_modules/kareem/index.js:307:15)
at /home/stieg/Devel/airfordable/mongoose-lean-virtuals/node_modules/mongoose/lib/query.js:4099:12
at cb (node_modules/mongoose/lib/query.js:1787:9)
at result (node_modules/mongodb/lib/utils.js:414:17)
at executeCallback (node_modules/mongodb/lib/utils.js:406:9)
at handleCallback (node_modules/mongodb/lib/utils.js:128:55)
at cursor.close (node_modules/mongodb/lib/operations/cursor_ops.js:224:62)
at handleCallback (node_modules/mongodb/lib/utils.js:128:55)
at completeClose (node_modules/mongodb/lib/cursor.js:893:14)
at _endSession (node_modules/mongodb/lib/cursor.js:904:37)
at Cursor._endSession (node_modules/mongodb-core/lib/cursor.js:195:5)
at Cursor._endSession (node_modules/mongodb/lib/cursor.js:226:59)
at Cursor.close (node_modules/mongodb/lib/cursor.js:904:19)
at cursor._next (node_modules/mongodb/lib/operations/cursor_ops.js:224:23)
at handleCallback (node_modules/mongodb-core/lib/cursor.js:204:5)
at _setCursorNotifiedImpl (node_modules/mongodb-core/lib/cursor.js:433:38)
at self._endSession (node_modules/mongodb-core/lib/cursor.js:441:46)
at ClientSession.endSession (node_modules/mongodb-core/lib/sessions.js:129:41)
at Cursor._endSession (node_modules/mongodb-core/lib/cursor.js:190:13)
at Cursor._endSession (node_modules/mongodb/lib/cursor.js:226:59)
at _setCursorNotifiedImpl (node_modules/mongodb-core/lib/cursor.js:441:17)
at setCursorNotified (node_modules/mongodb-core/lib/cursor.js:433:3)
at setCursorDeadAndNotified (node_modules/mongodb-core/lib/cursor.js:426:3)
at nextFunction (node_modules/mongodb-core/lib/cursor.js:554:5)
at Cursor.next (node_modules/mongodb-core/lib/cursor.js:763:3)
at Cursor._next (node_modules/mongodb/lib/cursor.js:211:36)
at fetchDocs (node_modules/mongodb/lib/operations/cursor_ops.js:217:12)
at cursor._next (node_modules/mongodb/lib/operations/cursor_ops.js:243:7)
at handleCallback (node_modules/mongodb-core/lib/cursor.js:204:5)
at nextFunction (node_modules/mongodb-core/lib/cursor.js:585:5)
at done (node_modules/mongodb-core/lib/cursor.js:651:7)
at queryCallback (node_modules/mongodb-core/lib/cursor.js:699:18)
at /home/stieg/Devel/airfordable/mongoose-lean-virtuals/node_modules/mongodb-core/lib/connection/pool.js:532:18
at process._tickCallback (internal/process/next_tick.js:61:11)
See title. Is this by design?
When upgrading to 0.7.0 I'm getting the following error due to
TypeError: Invalid value used as weak map key
at WeakMap.set (<anonymous>)
at applyVirtualsToResult (/root/repo/node_modules/mongoose-lean-virtuals/index.js:88:28)
at model.Query.attachVirtuals (/root/repo/node_modules/mongoose-lean-virtuals/index.js:80:10)
at applyVirtualsToChildren (/root/repo/node_modules/mongoose-lean-virtuals/index.js:126:20)
if (parent != null) {
documentParentsMap.set(res[i], parent);
}
Note that I was the asker for the .parent
function, but this code is not yet using it.
The issue is that there are code paths where this could be called but there's no results. E.g. the fix is to
if (parent != null) {
if (res[i]) {
documentParentsMap.set(res[i], parent);
}
}
I confirmed with logging that sometimes res[i] is undefined
and thus we need a truthy check.
Hi,
The virtual field in array of array can't be attached in mongoose-lean-virtuals@0.6.7, but it is okay in and before 0.6.5 version.
Below is the test code to reproduce the problem:
const chai = require("chai");
const expect = chai.expect;
const mongoose = require('mongoose');
const mongooseLeanVirtuals = require('mongoose-lean-virtuals');
const Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });
const subArraySchema = new Schema({
name: String,
});
subArraySchema.virtual('lowercase')
.get(function () {
return this.name.toLowerCase();
});
const arraySchema = new Schema({
subArray: [subArraySchema],
})
const testSchema = new Schema({
title: String,
array: [arraySchema],
});
testSchema.plugin(mongooseLeanVirtuals);
const testModel = mongoose.model('test', testSchema);
describe('test', () => {
before('Clear collection and add sample document', async () => {
await testModel.deleteMany({});
await new testModel({
title: 'test',
array: [{
subArray: [{
name: 'TEST',
}]
}]
}).save();
});
after('DB disconnect', async () => {
await mongoose.disconnect();
});
it('Check if virtual fields exist after lean', async () => {
const testDoc = await testModel.findOne({ title: 'test' }).lean({ virtuals: true });
const subObject = testDoc.array[0].subArray[0];
expect(subObject.name).to.be.equal('TEST');
expect(subObject.lowercase).to.be.equal('test');
});
});
And the test result is:
$ mocha index.js
(node:39410) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
test
1) Check if virtual fields exist after lean
0 passing (85ms)
1 failing
1) test
Check if virtual fields exist after lean:
AssertionError: expected undefined to equal 'test'
at Context.<anonymous> (index.js:51:39)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
nodejs: 12.18.0
mongodb: 4.2.7
mongoose: 5.9.21
mongoose-lean-virtuals: 0.6.7
chai: 4.2.0
mocha: 8.0.1
Hi there,
Thanks for the plugin. I just noticed that virtuals in discriminators don't work if the result of a query is an array.
The problem is how you check which discriminator schema to apply on line 43 - 51. In attachVirtuals
, res
can be an array, and each of the documents can have a different schema. This method, however, only works for single documents.
I will submit a PR for this, including unit tests.
mongoose(4.9.5) lean method is this
`
Query.prototype.lean = function(v) {
this._mongooseOptions.lean = arguments.length ? !!v : true;
return this;
};
`
lean function just get true or false, can't pass other params.
It's not work for me
I'm not able to use virtuals on populated models. I'm guessing that is not possible yet?
I have a mongoose schema as follow
const mongoose = require("mongoose");
const mongooseLeanVirtuals = require('mongoose-lean-virtuals');
const ImageSchema = new mongoose.Schema({
img: { type:String }
});
ImageSchema.virtual('img').get(function() {
return `${this.img}/crop/720/720`;
});
ImageSchema.plugin(mongooseLeanVirtuals);
const PostSchema = new mongoose.Schema(
{
title:{
type: String,
required: true,
trim: true
},
author:{
type: mongoose.Schema.Types.ObjectId,
ref:'Customer'
},
images: [ImageSchema]
},
{ timestamps: true }
);
module.exports = mongoose.model("Post", PostSchema);
Data result is
[
{
"_id": "64cb808d95a1ec6708a8e5e6",
"title": "First Post",
"author":{...},
"images": [],
"createdAt": "2023-08-03T10:33:31.253Z",
"updatedAt": "2023-08-03T10:33:31.253Z",
"__v": 0
},
{
"_id": "64cb829a95a1ec6708a8f9ab",
"title": "Next Post",
"author":{...},
"images": [
{
"_id": "64cb829a95a1ec6708a8f9ac",
"img": "image001.png"
},
{
"_id": "64cb829a95a1ec6708a8f9ad",
"img": "image002.png"
},
{
"_id": "64cb829a95a1ec6708a8f9ae",
"img": "image003.png"
}
],
"createdAt": "2023-08-03T10:34:02.173Z",
"updatedAt": "2023-08-03T10:34:02.173Z",
"__v": 0
}
]
In the database I already have a bunch of data, So I need to modify new image path in the return query as
img : "image003.png/crop/720/720"
Is it possible to achive this using mongoose virtual ?
await Post.find({}).lean({ virtuals: true }).lean().populate('author')
My expected result is
[
{
"_id": "64cb808d95a1ec6708a8e5e6",
"title": "First Post",
"author":{...},
"images": [],
"createdAt": "2023-08-03T10:33:31.253Z",
"updatedAt": "2023-08-03T10:33:31.253Z",
"__v": 0
},
{
"_id": "64cb829a95a1ec6708a8f9ab",
"title": "Next Post",
"author":{...},
"images": [
{
"_id": "64cb829a95a1ec6708a8f9ac",
"img": "image001.png/crop/720/720"
},
{
"_id": "64cb829a95a1ec6708a8f9ad",
"img": "image002.png/crop/720/720"
},
{
"_id": "64cb829a95a1ec6708a8f9ae",
"img": "image001.png/crop/720/720"
}
],
"createdAt": "2023-08-03T10:34:02.173Z",
"updatedAt": "2023-08-03T10:34:02.173Z",
"__v": 0
}
]
Do you want to request a feature or report a bug?
bug/feature
What is the current behavior?
parent's lean virtual is undefined
If the current behavior is a bug, please provide the steps to reproduce.
const assert = require('assert');
const mongoose = require('mongoose');
const mongooseLeanVirtuals = require('.');
const main = async () => {
await mongoose.connect('mongodb://localhost/my_database');
const childSchema = new mongoose.Schema({ firstName: String });
childSchema.virtual('uri').get(function() {
// This `uri` virtual is in a subdocument, so in order to get the
// parent's `uri` you need to use this plugin's `parent()` function.
const parent = this instanceof mongoose.Document
? this.parent()
: mongooseLeanVirtuals.parent(this)
;
return `${parent.uri}/child/${this._id}`;
});
const parentSchema = new mongoose.Schema({
child: childSchema
});
parentSchema.virtual('uri').get(function() {
return `/parent/${this._id}`;
});
parentSchema.plugin(mongooseLeanVirtuals);
const Parent = mongoose.model('Parent', parentSchema);
const doc = {
child: { }
};
await Parent.create(doc);
Parent
.findOne()
.lean({ virtuals: true })
.then(result => {
assert.equal(result.child.uri, `${result.uri}/child/${result.child.id}`);
});
};
main().catch(err => {
console.error(err);
process.exit(-1);
});
AssertionError [ERR_ASSERTION]: 'undefined/child/630c9d381351fdedf4eecb04' == '/parent/630c9d381351fdedf4eecb03/child/630c9d381351fdedf4eecb04'
at ...
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: 'undefined/child/630c9d381351fdedf4eecb04',
expected: '/parent/630c9d381351fdedf4eecb03/child/630c9d381351fdedf4eecb04',
operator: '=='
}
What is the expected behavior?
parent's lean virtual is available
What are the versions of Node.js, mongoose-lean-getters, and Mongoose are you are using? Note that "latest" is not a version.
node v18.7.0
[email protected]
[email protected]
Hi,
.lean with virtual was working fine when using mongoose 4.0. After updating it to mongoose 5.0.0, we get this error while using .lean with virtuals.
"Error: this.get is not a function",
Reproduction script below. If commenting out the validator, then the test passes. This issue is only present when this plugin is used.
const assert = require('assert')
const mongoose = require('mongoose')
const mongooseLeanVirtuals = require('mongoose-lean-virtuals')
const Schema = mongoose.Schema
it('Should work with discriminators that have middleware that query the base model', async () => {
// Setup our base model, with a virtual
const mediaSchema = new Schema(
{ file: String },
{ discriminatorKey: 'kind' }
)
mediaSchema.virtual('fileExtension').get(function () {
return this.file.split('.').pop()
})
// * Having this validator causes mongoose-lean-virtuals to fail! *
// Specifically, querying using the base model is what causes the error
mediaSchema.path('file').validate(async function (file) {
const Media = this.constructor
const mediaDoc = await Media.findOne({
_id: { $ne: this._id },
file
})
return !mediaDoc
}, 'The media file you are creating already exists')
// Everything works okay if we don't register the mongoose-lean-virtuals plugin
mediaSchema.plugin(mongooseLeanVirtuals)
// Discriminated schema
const photoSchema = new Schema({
position: String
}, { discriminatorKey: 'kind' })
const Media = mongoose.model('test-media', mediaSchema)
const Photo = Media.discriminator('photo', photoSchema)
// Create new Photo doc
let photo = new Photo({
file: 'cover.jpg',
position: 'left'
})
// This fails!
await photo.save()
assert.equal(photo.kind, 'photo')
assert.equal(photo.file, 'cover.jpg')
assert.equal(photo.position, 'left')
assert.equal(photo.fileExtension, 'jpg')
const result = await Media.findOne({}).lean({ virtuals: true }).exec()
assert.equal(result.fileExtension, 'jpg')
})
The following error is thrown:
ValidationError: photo validation failed: file: Cannot read property 'kind' of null
Using
mongoose-lean-virtuals
: 0.6.2mongoose
: 5.9.12node
: 14.2.0Do you want to request a feature or report a bug?
Bug
What is the current behavior?
If a sub-document is null and there is a virtual on it the sub-document is initialized as an object with the virtual instead of stay null
If the current behavior is a bug, please provide the steps to reproduce.
Consider the following setup:
import mongoose from "mongoose";
import { mongooseLeanVirtuals } from "mongoose-lean-virtuals";
mongoose.plugin(mongooseLeanVirtuals);
const ChildSchema = new mongoose.Schema({
age: { type: Number }
}, { _id: false })
const UserSchema = new mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
child: { type: ChildSchema }
});
UserSchema.virtual('child.parentName').get(function () {
return `${this.firstName} ${this.lastName}`;
});
const UserModel = mongoose.model('users', UserSchema);
run().catch(console.error);
And the following run
function:
async function run() {
await mongoose.connect('');
await UserModel.create({
firstName: 'Homer',
lastName: 'Simpson'
});
const result: any = await UserModel.findOne({}).lean({ virtuals: true }).exec();
assert.equal(result.firstName, 'Homer'); // Pass
assert.equal(result.lastName, 'Simpson'); // Pass
assert.equal(result.child, null); // Fail
console.log(result);
}
As you can see I expect that child
field will be null
but actually the value is: { parentName: 'Homer Simpson' }
.
If I tweak the create
a bit like that:
await UserModel.create({
firstName: 'Homer',
lastName: 'Simpson',
child: null
});
Then I get a runtime error Cannot read properties of null
which is even worst.
What is the expected behavior?
I expect that if a field is null
then no virtual should run on it.
What are the versions of Node.js, mongoose-lean-getters, and Mongoose are you are using? Note that "latest" is not a version.
Package | Version |
---|---|
mongoose | 6.5.0 |
mongoose-lean-getters | N/A |
mongoose-lean-virtuals | 0.9.1 |
Node.js | 16.13.0 |
Issue solved in mongoose: Automattic/mongoose#10683
In typegoose,
i want to no typing '{ virtuals : true }' but plugin can auto lean it.
when i use the mongooseLeanDefaults, i can use
@plugin(mongooseLeanDefaults as any, { defaults: true })
@plugin(mongooseLeanVirtuals as any, {
enabledByDefault: true,
virtuals: true,
lean: true,
})
export class SyncBBRecord{
@prop({ default: 'default_name' })
name?: string;
get vv() {
return 'vv';
}
}
const result = await this.mSyncBBRecord.findOne({}).lean();
console.log(result.name); // name has default value.
console.log(result.vv); // vv is virtuals.
the mongooseLeanDefaults plugin can auto lean,
but mongooseLeanVirtuals cannot.
i hope mongooseLeanVirtuals can esay use just like use mongooseLeanDefaults .
TypeError: Cannot read property 'length' of null
at applyVirtualsToChildren (C:\Users\usr\dev\ew\node_modules\mongoose-lean-virtuals\index.js:127:26)
at model.Query.attachVirtuals (C:\Users\usr\dev\ew\node_modules\mongoose-lean-virtuals\index.js:79:3)
at model.Query.<anonymous> (C:\Users\usr\dev\ew\node_modules\mongoose-lean-virtuals\index.js:52:22)
at C:\Users\usr\dev\ew\node_modules\mongoose-lean-virtuals\index.js:13:12
at C:\Users\usr\dev\ew\node_modules\mongoose\lib\query.js:4429:15
at cb (C:\Users\usr\dev\ew\node_modules\mongoose\lib\query.js:1907:9)
at C:\Users\usr\dev\ew\node_modules\mongodb\lib\utils.js:677:5
at handleCallback (C:\Users\usr\dev\ew\node_modules\mongodb\lib\utils.js:102:55)
at C:\Users\usr\dev\ew\node_modules\mongodb\lib\cursor.js:838:66
at C:\Users\usr\dev\ew\node_modules\mongodb\lib\utils.js:677:5
at C:\Users\usr\dev\ew\node_modules\mongodb\lib\cursor.js:923:9
at Cursor._endSession (C:\Users\usr\dev\ew\node_modules\mongodb\lib\core\cursor.js:394:7)
at C:\Users\usr\dev\ew\node_modules\mongodb\lib\cursor.js:921:12
at maybePromise (C:\Users\usr\dev\ew\node_modules\mongodb\lib\utils.js:665:3)
at Cursor.close (C:\Users\usr\dev\ew\node_modules\mongodb\lib\cursor.js:914:12)
at C:\Users\usr\dev\ew\node_modules\mongodb\lib\cursor.js:838:27
at handleCallback (C:\Users\usr\dev\ew\node_modules\mongodb\lib\core\cursor.js:31:5)
at C:\Users\usr\dev\ew\node_modules\mongodb\lib\core\cursor.js:680:38
at _setCursorNotifiedImpl (C:\Users\usr\dev\ew\node_modules\mongodb\lib\core\cursor.js:693:10)
at setCursorNotified (C:\Users\usr\dev\ew\node_modules\mongodb\lib\core\cursor.js:680:3)
at setCursorDeadAndNotified (C:\Users\usr\dev\ew\node_modules\mongodb\lib\core\cursor.js:673:3)
at nextFunction (C:\Users\usr\dev\ew\node_modules\mongodb\lib\core\cursor.js:827:5)
When you have a schema that contains another schema with virtual properties, virtuals on the parent schema that access a child schema's virtuals do not behave properly.
For example, take two schemas, Foo and Bar.
number
property and a doubleNumber
virtual property.barDoubleTotal
) that sums it's bars' doubleNumber valuesWhen you create them a Foo with a couple of child Bars, foo.bar[0].doubleNumber
and foo.barDoubleTotal
work as expected. After storage and retrieval foo.bar[0].doubleNumber
works as expected, but foo.barDoubleTotal
returns NaN instead of summing the array of bar's doubleNumber virtual properties.
Code below to (hopefully) clearly illustrate the issue...
const mongoose = require('mongoose');
const mongooseLeanVirtuals = require('mongoose-lean-virtuals');
// Bar Model
const barSchema = new mongoose.Schema({
number: { default: 2, type: Number }
});
barSchema.plugin(mongooseLeanVirtuals);
barSchema.virtual('doubleNumber').get(function() {
return this.number * 2;
});
const Bar = mongoose.model('Bar', barSchema);
// Foo Model
const fooSchema = new mongoose.Schema({
bars: [Bar.schema],
number: { type: Number }
});
fooSchema.plugin(mongooseLeanVirtuals);
// virtual that totals virtuals
fooSchema.virtual('barDoubleTotal').get(function() {
return this.bars.map(b => b.doubleNumber).reduce((a, c) => a + c);
});
fooSchema.virtual('barTotal').get(function() {
return this.bars.map(b => b.number).reduce((a, c) => a + c);
});
fooSchema.virtual('doubleNumber').get(function() {
return this.number * 2;
});
const Foo = mongoose.model('Foo', fooSchema);
var bar1 = new Bar({ number: 1 });
var bar2 = new Bar({ number: 3 });
var foo = new Foo({
bars: [ bar1, bar2 ],
number: 5
});
console.log('\nInitial state:\n***************');
console.log(`✅ plain property\tfoo.number: ${foo.number}`);
console.log(`✅ virtual property\tfoo.doubleNumber: ${foo.doubleNumber}`);
console.log(`✅ sum child properties\tfoo.barTotal: ${foo.barTotal}`);
console.log(`✅ sum child virtuals\tfoo.barDoubleTotal: ${foo.barDoubleTotal}`);
console.log(`✅ child virtual\t\tfoo.bars[0].doubleNumber: ${foo.bars[0].doubleNumber}`);
console.log(`✅ child virtual\t\tfoo.bars[1].doubleNumber: ${foo.bars[1].doubleNumber}`);
console.log('\nstoring...');
mongoose.connect('mongodb://127.0.0.1/nested-virtuals', function() {
foo.save(function(err, savedFoo) {
if (err) {
console.err(err);
process.exit(1);
}
console.log('retrieving...');
Foo.findOne({_id: savedFoo._id}).lean({ virtuals: true }).exec(function(err, retrievedFoo) {
if (err) {
console.err(err);
process.exit(1);
}
console.log('\nRetrieved state:\n***************');
console.log(`✅ retrievedFoo.number: ${retrievedFoo.number}`);
console.log(`✅ retrievedFoo.doubleNumber: ${retrievedFoo.doubleNumber}`);
console.log(`✅ retrievedFoo.barTotal: ${retrievedFoo.barTotal}`);
console.log(`❌ retrievedFoo.barDoubleTotal: ${retrievedFoo.barDoubleTotal}`);
console.log(`✅ retrievedFoo.bars[0].doubleNumber: ${retrievedFoo.bars[0].doubleNumber}`);
console.log(`✅ retrievedFoo.bars[1].doubleNumber: ${retrievedFoo.bars[1].doubleNumber}`);
console.log('\nDone.\n');
process.exit(0);
});
});
});
Initial state:
***************
✅ plain property foo.number: 5
✅ virtual property foo.doubleNumber: 10
✅ sum child properties foo.barTotal: 4
✅ sum child virtuals foo.barDoubleTotal: 8
✅ child virtual foo.bars[0].doubleNumber: 2
✅ child virtual foo.bars[1].doubleNumber: 6
storing...
(node:39847) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/4.x/docs/connections.html#use-mongo-client
(node:39847) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
retrieving...
Retrieved state:
***************
✅ retrievedFoo.number: 5
✅ retrievedFoo.doubleNumber: 10
✅ retrievedFoo.barTotal: 4
❌ retrievedFoo.barDoubleTotal: NaN
✅ retrievedFoo.bars[0].doubleNumber: 2
✅ retrievedFoo.bars[1].doubleNumber: 6
Done.
(Edited for brevity)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.