使用异步瀑布填充查询选项
Populate Query Options with Async Waterfall
我正在尝试 mongoose populate
查询选项,但我不知道为什么查询选项不起作用。
我有用户模式:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema(
{
username: { type: String, required: true },
email: { type: String },
name: { type: String },
address: { type: String }
},
{ timestamps: true }
);
module.exports = mongoose.model('User', UserSchema);
和提要架构:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const FeedSchema = new Schema(
{
user: { type: Schema.ObjectId, ref: 'User' },
notes: { type: String, required: true },
trx_date: { type: Date },
status: { type: Boolean, Default: true }
},
{ timestamps: true }
);
FeedSchema.set('toObject', { getters: true });
module.exports = mongoose.model('Feed', FeedSchema);
我想通过 user
id 找到所有 feed
,我使用 async waterfall
就像下面的代码:
async.waterfall([
function(callback) {
User
.findOne({ 'username': username })
.exec((err, result) => {
if (result) {
callback(null, result);
} else {
callback(err);
}
});
},
function(userid, callback) {
// find user's feed
Feed
.find({})
// .populate('user', {_id: userid._id}) <== this one also doesn't work
.populate({
path: 'user',
match: { '_id': { $in: userid._id } }
})
.exec(callback);
}
], function(err, docs) {
if (err) {
return next(err);
}
console.log(docs);
});
使用上面的代码,我得到了所有提要,但查询选项似乎根本不起作用,我做错了吗?
如有任何帮助,我们将不胜感激。
当 _id
的值已经存储在 "user"
属性 "before" 中时,不确定为什么要匹配 "after" 人口你甚至填充。
因此,它实际上只是 .find()
的简单 "query" 条件:
async.waterfall([
(callback) =>
User.findOne({ 'username': username }).exec(callback),
(user, callback) => {
if (!user) callback(new Error('not found')); // throw here if not found
// find user's feed
Feed
.find({ user: user._id })
.populate('user')
.exec(callback);
}
], function(err, docs) {
if (err) {
return next(err);
}
console.log(docs);
});
当然要记住 .findOne()
返回整个文档,所以您只需要在新查询中使用 _id
属性。另请注意,初始瀑布函数中的 "juggling" 不是必需的。如果有错误,那么它将 "fast fail" 到结束回调,否则将结果传递给不存在的地方。将 "not found" 改为下一个方法。
当然这真的没有必要,因为 "Promises" 已经存在了一段时间,你真的应该使用它们:
User.findOne({ "username": username })
.then( user => Feed.find({ "user": user._id }).populate('user') )
.then( feeds => /* do something */ )
.catch(err => /* do something with any error */)
或者确实在 MongoDB 支持的地方使用 $lookup
:
User.aggregate([
{ "$match": { "username": username } },
{ "$lookup": {
"from": Feed.collection.name,
"localField": "_id",
"foreignField": "user",
"as": "feeds"
}}
]).then( user => /* User with feeds in array /* )
它的输出有点不同,您实际上可以通过一些操作将其更改为看起来相同,但这应该让您大致了解。
重要的是,通常最好让服务器进行连接而不是发出多个请求,这至少会增加延迟。
我正在尝试 mongoose populate
查询选项,但我不知道为什么查询选项不起作用。
我有用户模式:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema(
{
username: { type: String, required: true },
email: { type: String },
name: { type: String },
address: { type: String }
},
{ timestamps: true }
);
module.exports = mongoose.model('User', UserSchema);
和提要架构:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const FeedSchema = new Schema(
{
user: { type: Schema.ObjectId, ref: 'User' },
notes: { type: String, required: true },
trx_date: { type: Date },
status: { type: Boolean, Default: true }
},
{ timestamps: true }
);
FeedSchema.set('toObject', { getters: true });
module.exports = mongoose.model('Feed', FeedSchema);
我想通过 user
id 找到所有 feed
,我使用 async waterfall
就像下面的代码:
async.waterfall([
function(callback) {
User
.findOne({ 'username': username })
.exec((err, result) => {
if (result) {
callback(null, result);
} else {
callback(err);
}
});
},
function(userid, callback) {
// find user's feed
Feed
.find({})
// .populate('user', {_id: userid._id}) <== this one also doesn't work
.populate({
path: 'user',
match: { '_id': { $in: userid._id } }
})
.exec(callback);
}
], function(err, docs) {
if (err) {
return next(err);
}
console.log(docs);
});
使用上面的代码,我得到了所有提要,但查询选项似乎根本不起作用,我做错了吗?
如有任何帮助,我们将不胜感激。
当 _id
的值已经存储在 "user"
属性 "before" 中时,不确定为什么要匹配 "after" 人口你甚至填充。
因此,它实际上只是 .find()
的简单 "query" 条件:
async.waterfall([
(callback) =>
User.findOne({ 'username': username }).exec(callback),
(user, callback) => {
if (!user) callback(new Error('not found')); // throw here if not found
// find user's feed
Feed
.find({ user: user._id })
.populate('user')
.exec(callback);
}
], function(err, docs) {
if (err) {
return next(err);
}
console.log(docs);
});
当然要记住 .findOne()
返回整个文档,所以您只需要在新查询中使用 _id
属性。另请注意,初始瀑布函数中的 "juggling" 不是必需的。如果有错误,那么它将 "fast fail" 到结束回调,否则将结果传递给不存在的地方。将 "not found" 改为下一个方法。
当然这真的没有必要,因为 "Promises" 已经存在了一段时间,你真的应该使用它们:
User.findOne({ "username": username })
.then( user => Feed.find({ "user": user._id }).populate('user') )
.then( feeds => /* do something */ )
.catch(err => /* do something with any error */)
或者确实在 MongoDB 支持的地方使用 $lookup
:
User.aggregate([
{ "$match": { "username": username } },
{ "$lookup": {
"from": Feed.collection.name,
"localField": "_id",
"foreignField": "user",
"as": "feeds"
}}
]).then( user => /* User with feeds in array /* )
它的输出有点不同,您实际上可以通过一些操作将其更改为看起来相同,但这应该让您大致了解。
重要的是,通常最好让服务器进行连接而不是发出多个请求,这至少会增加延迟。