Do you want to request a feature or report a bug?
Bug
What is the current behavior?
justOne: true
option set, but the virtual field returns the same first item in the output result. justOne: false
it works correctly. But it returns an array instead of single object.Summary: the detailItem
in the second item of array have _id
does not same with idItem
. Data output looks like:
"items":[
{
"value":"1",
"idItem":"b3d379d5-8eb2-4c52-a098-7021bdc66eb6",
"idItemParent":"38d801d5-20f7-49df-b394-5afdfba6807d",
"_id":"0a65878c-d2b5-4c47-8de0-61cf65b64057",
"id":"0a65878c-d2b5-4c47-8de0-61cf65b64057",
"itemDetail":{
"_id":"b3d379d5-8eb2-4c52-a098-7021bdc66eb6",
"name":"DV",
"ghi_chu":"Chi phà dịch vụ",
"idItemParent":"38d801d5-20f7-49df-b394-5afdfba6807d",
"createdAt":"2018-08-14T17:22:48.415Z",
"updatedAt":"2018-08-14T17:22:48.415Z",
"id":"b3d379d5-8eb2-4c52-a098-7021bdc66eb6"
}
},
{
"value":"2",
"idItem":"fabbb077-5d59-4576-9fd9-97d47f2db12e",
"idItemParent":"38d801d5-20f7-49df-b394-5afdfba6807d",
"_id":"e2402c16-7d1a-4f11-95fe-76e060c36967",
"id":"e2402c16-7d1a-4f11-95fe-76e060c36967",
"itemDetail":{ // here is the problem, output is same with the first item
"_id":"b3d379d5-8eb2-4c52-a098-7021bdc66eb6", // not same `idItem`
"code":"",
"name":"DV",
"ghi_chu":"Chi phà dịch vụ",
"idItemParent":"38d801d5-20f7-49df-b394-5afdfba6807d",
"createdAt":"2018-08-14T17:22:48.415Z",
"updatedAt":"2018-08-14T17:22:48.415Z",
"id":"b3d379d5-8eb2-4c52-a098-7021bdc66eb6"
}
}
],
If the current behavior is a bug, please provide the steps to reproduce.
Here are the steps:
var uuid = require("uuid");
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ReportItemSchema = new Schema({
_id: {
type: String,
default: uuid.v4
},
idItem: {
type: String,
ref: 'Item'
},
idItemParent: {
type: String,
ref: 'Item'
},
value: String,
mediaType: String
}, {
timestamps: true,
toJSON: {
virtuals: true
},
toObject: {
virtuals: true
}
});
var ReportSchema = new Schema({
_id: {
type: String,
default: uuid.v4
},
items: [ReportItemSchema],
status: {
type: Number,
default: 0
}
}, {
id: true,
timestamps: true,
toJSON: {
virtuals: true
},
toObject: {
virtuals: true
}
});
/**
* Virtual fields definition
*/
ReportItemSchema.virtual('itemDetail', {
ref: 'Item',
localField: 'idItem',
foreignField: '_id',
justOne: true // here is the problem
});
ReportItemSchema.virtual('itemParent', {
ref: 'Item',
localField: 'idItemParent',
foreignField: '_id',
justOne: true
});
// Model Item definition
var ItemSchema = new Schema({
_id: {
type: String,
default: uuid.v4
},
code: String,
name: String,
ghi_chu: String,
idItemParent: String
}, {
id: true,
timestamps: true,
toJSON: {
virtuals: true
},
toObject: {
virtuals: true
}
});
/**
* Virtual fields definition
*/
ItemSchema.virtual("parent", {
ref: 'Item',
localField: 'idItemParent',
foreignField: '_id',
justOne: true
}).set(function (value) {
if (value) {
this.idItemParent = value._id;
}
});
/**
* Model definition
*/
var ItemModel = mongoose.model("Item", ItemSchema);
var ReportModel = mongoose.model("Report", ReportSchema);
findOne
read(req, res) {
var id = req.param('id');
this.ReportModel.findOne({
_id: id
})
.populate('items.itemDetail')
.populate('items.itemParent')
.then((doc) => {
res.ok(doc)
})
.catch((err) => {
res.error(err);
})
}
{
"status":0,
"_id":"a6a14b80-8795-4864-9359-0b28b44fb6b9",
"items":[
{
"value":"1",
"idItem":"b3d379d5-8eb2-4c52-a098-7021bdc66eb6",
"idItemParent":"38d801d5-20f7-49df-b394-5afdfba6807d",
"_id":"0a65878c-d2b5-4c47-8de0-61cf65b64057",
"id":"0a65878c-d2b5-4c47-8de0-61cf65b64057",
"itemDetail":{
"_id":"b3d379d5-8eb2-4c52-a098-7021bdc66eb6",
"name":"DV",
"ghi_chu":"Chi phà dịch vụ",
"idItemParent":"38d801d5-20f7-49df-b394-5afdfba6807d",
"createdAt":"2018-08-14T17:22:48.415Z",
"updatedAt":"2018-08-14T17:22:48.415Z",
"__v":0,
"parent":null,
"id":"b3d379d5-8eb2-4c52-a098-7021bdc66eb6"
},
"itemParent":{
"_id":"38d801d5-20f7-49df-b394-5afdfba6807d",
"name":"Thống kê chi phÃ",
"ghi_chu":"",
"createdAt":"2018-08-14T10:26:23.878Z",
"updatedAt":"2018-08-14T10:26:23.878Z",
"__v":0,
"parent":null,
"id":"38d801d5-20f7-49df-b394-5afdfba6807d"
}
},
{
"value":"2",
"idItem":"fabbb077-5d59-4576-9fd9-97d47f2db12e",
"idItemParent":"38d801d5-20f7-49df-b394-5afdfba6807d",
"_id":"e2402c16-7d1a-4f11-95fe-76e060c36967",
"id":"e2402c16-7d1a-4f11-95fe-76e060c36967",
"itemDetail":{ // here is the problem, output is same with the first item
"_id":"b3d379d5-8eb2-4c52-a098-7021bdc66eb6",
"code":"",
"name":"DV",
"ghi_chu":"Chi phà dịch vụ",
"idItemParent":"38d801d5-20f7-49df-b394-5afdfba6807d",
"createdAt":"2018-08-14T17:22:48.415Z",
"updatedAt":"2018-08-14T17:22:48.415Z",
"__v":0,
"parent":null,
"id":"b3d379d5-8eb2-4c52-a098-7021bdc66eb6"
},
"itemParent":{
"_id":"38d801d5-20f7-49df-b394-5afdfba6807d",
"name":"Thống kê chi phÃ",
"ghi_chu":"",
"createdAt":"2018-08-14T10:26:23.878Z",
"updatedAt":"2018-08-14T10:26:23.878Z",
"__v":0,
"parent":null,
"id":"38d801d5-20f7-49df-b394-5afdfba6807d"
}
}
],
"createdAt":"2018-08-14T19:19:31.170Z",
"updatedAt":"2018-08-15T07:28:47.823Z",
"__v":0,
"id":"a6a14b80-8795-4864-9359-0b28b44fb6b9"
}
What is the expected behavior?
Since justOne: true
is set for the virtual field itemDetail, the expected behavior is for itemDetail to contain a single object, and have its own value which references to Item.
Please mention your node.js, mongoose and MongoDB version.
node.js: v8.11.1
MongoDB: v3.2.8
mongoose: v5.2.8
Confirmed, below script demonstrates the issue:
const assert = require('assert');
const mongoose = require('mongoose');
mongoose.set('debug', true);
const GITHUB_ISSUE = `gh6867`;
const connectionString = `mongodb://localhost:27017/${ GITHUB_ISSUE }`;
const { Schema } = mongoose;
run().then(() => console.log('done')).catch(error => console.error(error.stack));
async function run() {
await mongoose.connect(connectionString);
await mongoose.connection.dropDatabase();
const ReportItemSchema = new Schema({
idItem: {
type: String,
ref: 'Item'
},
value: String,
mediaType: String
});
const ReportSchema = new Schema({
_id: String,
items: [ReportItemSchema],
status: {
type: Number,
default: 0
}
});
ReportItemSchema.virtual('itemDetail', {
ref: 'Item',
localField: 'idItem',
foreignField: '_id',
justOne: true // here is the problem
});
var ItemSchema = new Schema({
_id: String,
code: String,
name: String,
ghi_chu: String,
idItemParent: String
});
ItemSchema.virtual("parent", {
ref: 'Item',
localField: 'idItemParent',
foreignField: '_id',
justOne: true
});
var ItemModel = mongoose.model("Item", ItemSchema);
var ReportModel = mongoose.model("Report", ReportSchema);
await ItemModel.create({ _id: 'foo' });
await ReportModel.create({
_id: 'test',
items: [{ idItem: 'foo' }, { idItem: 'bar' }]
});
const doc = await ReportModel.findOne({}).populate('items.itemDetail');
console.log(doc.toObject({ virtuals: true }).items);
}
Most helpful comment
Confirmed, below script demonstrates the issue: