New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow overwriting localField
and foreignField
when populating virtuals
#6963
Comments
@lcw0622 The following complete example shows that population works. Can you edit it to show the error you are seeing? 6963.js#!/usr/bin/env node
'use strict';
const assert = require('assert');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/test', { useMongoClient: true});
const conn = mongoose.connection;
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: String,
username: String
});
const projectSchema = new Schema({
name: String,
username: String
});
projectSchema.virtual('userInfo', {
ref: 'user',
localField: 'username',
foreignField: 'username',
justOne: true
});
const User = mongoose.model('user', userSchema);
const Project = mongoose.model('project', projectSchema);
const user = new User({ name: 'Billy', username: 'quickdraw' });
const project = new Project({ name: 'Outlaw', username: user.username });
async function run() {
assert.strictEqual(mongoose.version, '4.12.3');
await conn.dropDatabase();
await user.save();
await project.save();
let doc = await Project.findOne({}).populate('userInfo');
assert.strictEqual(doc.userInfo.name, 'Billy');
console.log('Assertions passed.');
return conn.close();
}
run(); Output:
|
did you also change the creation of the project doc to reflect the new field Here is the same code as above but with the Project path 6963.js#!/usr/bin/env node
'use strict';
const assert = require('assert');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/test', { useMongoClient: true});
const conn = mongoose.connection;
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: String,
username: String
});
const projectSchema = new Schema({
name: String,
erp: String // changed
});
projectSchema.virtual('userInfo', {
ref: 'user',
localField: 'erp', // changed
foreignField: 'username',
justOne: true
});
const User = mongoose.model('user', userSchema);
const Project = mongoose.model('project', projectSchema);
const user = new User({ name: 'Billy', username: 'quickdraw' });
const project = new Project({ name: 'Outlaw', erp: user.username }); // changed
async function run() {
assert.strictEqual(mongoose.version, '4.12.3');
await conn.dropDatabase();
await user.save();
await project.save();
let doc = await Project.findOne({}).populate('userInfo');
assert.strictEqual(doc.userInfo.name, 'Billy');
console.log('Assertions passed.');
return conn.close();
}
run(); Output:
|
Thanks, In fact I use #!/usr/bin/env node
'use strict';
const assert = require('assert');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/test', { useMongoClient: true});
const conn = mongoose.connection;
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: String,
username: String
});
const projectSchema = new Schema({
name: String,
username: String
});
projectSchema.virtual('userInfo', {
ref: 'user',
localField: 'username',
foreignField: 'username',
justOne: true
});
const User = mongoose.model('user', userSchema);
const Project = mongoose.model('project', projectSchema);
const user = new User({ name: 'Billy', username: 'quickdraw' });
const project = new Project({ name: 'Outlaw', username: user.username });
async function run() {
assert.strictEqual(mongoose.version, '4.12.3');
await conn.dropDatabase();
await user.save();
await project.save();
let doc = await Project.findOne({}).populate('userInfo');
let plainObj = doc.toObject()
assert.strictEqual(plainObj.userInfo.name, 'Billy');
console.log('Assertions passed.');
return conn.close();
}
run(); Output:
|
@lcw0622 you need to set the toObject virtuals option on the project schema to true in order to get virtual fields in the output of toObject(). const projectSchema = new Schema({
name: String,
username: String
}, { toObject: { virtuals: true } }); or const projectSchema = new Schema({
name: String,
username: String
});
projectSchema.set('toObject', { virtuals: true }); |
@lineus It take effect! Thanks a lot~ Maybe I need ready API docs more careful T_T |
@lineus By the way, may I ask for why not add var personSchema = Schema({
_id: Schema.Types.ObjectId,
name: String,
age: Number,
stories: [{ type: String, ref: 'Story', foreignField: 'storyName' }]
}); orPerson.
findOne({ name: 'Ian Fleming' }).
populate({
path: 'stories',
foreignField: 'storyName'
}). |
@vkarpov15 I'll let you answer the question. Why do only virtuals accept the local and foreign field options as opposed to being able to set them in the schema or the populate object. |
Re: setting |
Thanks ,@lineus and @vkarpov15 ~ SELECT
FIELD_A,
(SELECT T_B.FIELD_B FROM T_B WHERE T_B.FIELD_A = T_A.FIELD_A) AS FIELD_B
FROM T_A
WHERE T_A='SOME OTHER CONDITIONS' |
@lcw0622 unlikely to happen anytime soon, but thanks for the suggestion |
localField
and foreignField
when populating virtuals
Island rhythms/gh 6963 Can overwrite foreignField
It return without
userInfo
field, but if I changeforeignField
to_id
, it will report an error like:CastError: Cast to ObjectId failed for value "username" at path "_id" for model "User".
Mongoose: 4.12.3
MongoDB: 2.2.34
NodeJS: 8.11.2
The text was updated successfully, but these errors were encountered: