猫鼬如何填充非 ID 字段或如何手动实现并行承诺填充
mongoose how to populate non-id field or how to implement parallel promise population manually
我想用 mongoose 填充一个非 id 字段,并且已经在这里找到这些问题:
link1
link2
原来mongoose现在不支持这个功能了。未解决的问题在这里:https://github.com/Automattic/mongoose/issues/2562
所以现在,我想用额外的查询手动填充。但是我在做的时候遇到了一些问题
我有两个模式(回复、用户):
这是回复架构,author_id 引用用户集合的用户名字段而不是 _id;
var ReplySchema = new Schema({
'content' : {
type: String,
required: true
},
'author_id' : {
type: String,
ref: 'users'
},
});
当我收到全部回复时。喜欢:
replies [ {
content: 'comments one',
author_id: 'raynlon',
},
{
content: 'comments two',
author_id: 'raynlon',
} ]
从这里开始,我正在进一步从用户 table 查询作者,我所做的是:
var replies = yield query.exec(); // which already got all the replies
var final = [];
for (var i = 0; i < replies.length; i++) {
co(function*(){
var data = yield User.Model.findOne({username: replies[i].author_id}).select('username email avatar gravatar_id name').exec();
return data;
}).then(function(value) {
final.push(value);
});
}
return final // I need to return the modified data back to the client
我总是空着[];
这是因为 for 循环中的异步代码?
我还找到了一些解决方案,例如:
Promise.all(), q.all()
这些有点类似的承诺......
但是我不知道怎么办..
我使用的 co 库说 co() 应该作为承诺返回,理论上,我们可以然后注入 Promise.all([]),但它不起作用......所以任何人都可以帮我解决这个问题?
好的,问题是:您创建了变量 final
并在之后创建了变量 returns,这发生在 Mongo-Query 执行之前。
解决方法:把Promises推送到final
,然后在回复客户端的时候一起解决。
function queryAsync() {
var replies = yield query.exec(); // which already got all the replies
var final = [];
for (var i = 0; i < replies.length; i++) {
final.push(
User.Model.findOne({
username: replies[i].author_id
}).select('username email avatar gravatar_id name').exec()
)
}
return final; // and array with promises is returned
}
// later in your handler ..
function handler(request, response) {
// ..
// query here, and resolve promises in final here
bluebird.all(queryAsync()).then(function(final) {
// all promises resolved
response.send(final);
})
// ..
}
我想用 mongoose 填充一个非 id 字段,并且已经在这里找到这些问题:
link1
link2
原来mongoose现在不支持这个功能了。未解决的问题在这里:https://github.com/Automattic/mongoose/issues/2562
所以现在,我想用额外的查询手动填充。但是我在做的时候遇到了一些问题
我有两个模式(回复、用户):
这是回复架构,author_id 引用用户集合的用户名字段而不是 _id;
var ReplySchema = new Schema({
'content' : {
type: String,
required: true
},
'author_id' : {
type: String,
ref: 'users'
},
});
当我收到全部回复时。喜欢:
replies [ {
content: 'comments one',
author_id: 'raynlon',
},
{
content: 'comments two',
author_id: 'raynlon',
} ]
从这里开始,我正在进一步从用户 table 查询作者,我所做的是:
var replies = yield query.exec(); // which already got all the replies
var final = [];
for (var i = 0; i < replies.length; i++) {
co(function*(){
var data = yield User.Model.findOne({username: replies[i].author_id}).select('username email avatar gravatar_id name').exec();
return data;
}).then(function(value) {
final.push(value);
});
}
return final // I need to return the modified data back to the client
我总是空着[];
这是因为 for 循环中的异步代码?
我还找到了一些解决方案,例如: Promise.all(), q.all() 这些有点类似的承诺......
但是我不知道怎么办..
我使用的 co 库说 co() 应该作为承诺返回,理论上,我们可以然后注入 Promise.all([]),但它不起作用......所以任何人都可以帮我解决这个问题?
好的,问题是:您创建了变量 final
并在之后创建了变量 returns,这发生在 Mongo-Query 执行之前。
解决方法:把Promises推送到final
,然后在回复客户端的时候一起解决。
function queryAsync() {
var replies = yield query.exec(); // which already got all the replies
var final = [];
for (var i = 0; i < replies.length; i++) {
final.push(
User.Model.findOne({
username: replies[i].author_id
}).select('username email avatar gravatar_id name').exec()
)
}
return final; // and array with promises is returned
}
// later in your handler ..
function handler(request, response) {
// ..
// query here, and resolve promises in final here
bluebird.all(queryAsync()).then(function(final) {
// all promises resolved
response.send(final);
})
// ..
}