图式数组中的mongoose数

我需要在模式中查找元素,然后统计它们发送的总消息。 我已经尝试了以上代码,但不适合我。

User.find({type: 'psycologist'}).exec(function (err, users) { if(err){ callback(new Error("Something went wrong"), null); }else{ Message.count({userFrom: { "$in" : users} }).exec(function (err, counter) { if(err){ callback(new Error("Something went wrong."), null); }else{ console.log(counter); //displays 0 callback(null, counter); } }); } }); 

消息架构

 var schema = new Schema({ content: {type: String, required: true}, type: {type: String, required: true, default: 'text'}, status: {type: String, default: 'not_read'}, created_at: {type: Date, default: Date.now}, userFrom: {type: Schema.Types.ObjectId, ref: 'User', required: true}, userTo: {type: Schema.Types.ObjectId, ref: 'User', required: true} }); 

用户架构

 var schema = new Schema({ name: {type: String, required: true}, email: {type: String, required: true, unique: true}, phone: {type: String, required: true}, password: {type: String, required: true, select: false}, type: {type: String, required: true}, created_at: {type: Date, required: true, default: Date.now} }); 

有人知道如何解决这个问题或更好的办法吗? 提前致谢。

如果有任何Mongo专家在这里可以告诉我关于这个查询大量数据的性能的更多细节。

问题是你第一次查找的结果是一组用户,它是完整的文档。 您只能在$ in查找操作符中使用一个数组值。

将其更改为:

 User.find({type: 'psycologist'}).exec(function (err, users) { if(err){ callback(new Error("Something went wrong"), null); }else{ var MyUserIdArray = users.map(function(x) { return x._id} ); Message.count({userFrom: { "$in" : MyUserIdArray} }).exec(function (err, counter) { if(err){ callback(new Error("Something went wrong."), null); }else{ console.log(counter); //displays 0 callback(null, counter); } }); } }); 

一个更好的方法是使用聚合框架来运行一个使用$lookup操作符的pipe道对来自users集合的messages集合执行“左连接”。

考虑运行以下聚合pipe道:

 Users.aggregate([ { "$match": { "type": "psycologist"} }, { "$lookup": { "from": "messages", "localField": "_id", "foreignField": "userFrom", "as": "messagesFrom" } }, { "$project": { "messages": { "$size": "$messagesFrom" } } }, { "$group": { "_id": null, "counter": { "$sum": "$messages" } } } ]).exec(function(err, result) { if(err){ callback(new Error("Something went wrong."), null); }else{ console.log(JSON.stringify(result, null, 4)); callback(null, result[0].counter); } }); 

在上面的聚合操作中,第一步是$match运算符,它对文档stream进行过滤,只允许匹配的文档未修改地传递到下一个stream水线阶段,并且可以将MongoDB查询语法作为参数。 这与MongoDB Collection的find()方法和SQL的WHERE子句以及filter{ "$match": { "type": "psycologist"} }类似。

 User.find({type: 'psycologist'}) 

在下一个pipe道中,过滤后的文档被传递给$lookup操作符,该操作对同一数据库中的messages集合执行左外部连接,以过滤“已连接”集合中的文档进行处理。 “as”选项是要添加到input文档的新数组字段的名称。 新的数组字段包含来自“from”集合的匹配文档。

您将需要获取此数组的长度,因为它指示每个用户的消息数量。 这可以在下一个pipe道中使用$project操作符来重新生成stream中的每个文档,包括,排除或重命名字段,注入计算字段,使用mathexpression式,date,string和/或逻辑比较,布尔,控制)expression式。

在这种情况下,您使用$size操作符返回数组中元素的数量,因此您可以获得每个用户的消息数量。

最后的pipe道步骤是汇总所有文档的$group 。 这将通过指定的标识符expression式对input文档进行分组,并应用累加器expression式。 但在这种情况下,您可以指定一个_id值为null来计算所有input文档的累计值。 您使用在messages字段上应用的$sum累加器运算符(从上一个pipe道计算得出)汇总所有消息计数,从而获得来自特定用户types的消息总数。

尝试

 User.find({type: 'psycologist'}, {_id: 1}).exec(function (err, users) { if(err){ callback(new Error("Something went wrong"), null); }else{ var ids = users.map(function(user){ return user._id; }) Message.count({userFrom: { "$in" : ids } }).exec(function (err, counter) { if(err){ callback(new Error("Something went wrong."), null); }else{ console.log(counter); //displays 0 callback(null, counter); } }); } });