这是文件的结构。
{
"_id" : ObjectId("5548f1cc0dcd6bd925a71ae2"), //document id
"messages" : [
{
"subject" : "NEW ++ SUBJECT",
"from" : ObjectId("5534b2992a104ed914435c31"),
"_id" : ObjectId("5548f1cc0dcd6bd925a71ae3"),
"created" : ISODate("2015-05-05T16:37:32.832Z"),
"read" : false,
"message" : "FIRST MESSAGE",
"participants" : [
ObjectId("5534b2992a104ed914435c31"),
ObjectId("5530af38576214dd3553331c")
]
},
{
"subject" : "dfgsd",
"from" : ObjectId("5534b2992a104ed914435c98"),//logged In USer
"_id" : ObjectId("5548f1df0dcd6bd925a71ae4"),
"created" : ISODate("2015-05-05T16:37:51.455Z"),
"read" : false,
"message" : "rdfgdgfd",
"participants" : [
ObjectId("5534b2992a104ed914435c98"),//logged In USer
ObjectId("5530af38576214dd3553331c")
]
}
"participants" : [
ObjectId("5534b2992a104ed914435c98"),//logged In USer
ObjectId("5534b2992a104ed914435c31"),
ObjectId("5530af38576214dd3553331c")
],
"__v" : 3
}
我想得到其“读取”值为“false”的消息数组的消息对象& 'from'不等于用户登录(此处登录用户为5534b2992a104ed914435c98)。并且文档的'参与者'数组必须包含登录的用户ID(5534b2992a104ed914435c98)。这是我试过的查询。
db.conversations.find({participants:ObjectId('5534b2992a104ed914435c98'),'messages.read':false,'messages.from':{$ne:ObjectId('5534b2992a104ed914435c98')}}).pretty().
基本上我正在尝试获取未读消息的数量。 我是mongodb / mongoose的新手。如果您在问题中发现错误,请纠正我。
答案 0 :(得分:8)
如果您尝试根据“读取”消息数组的条件获取未读消息的数量。价值是“假”' &安培; '从'不等于用户登录(此处登录用户为5534b2992a104ed914435c98
)且文档的'participants'
数组必须包含登录用户ID 5534b2992a104ed914435c98
,然后 {{ 3}} 方法应该可以帮助您获得所需的结果。
聚合管道应该具有满足上述要求的第一个管道阶段aggregation framework查询。这会过滤需要在管道流中进一步处理的文档。
对于在处理之前不使用$match
运算符首先展平消息数组的解决方案,请考虑 $unwind
和 $filter
<运营商如下:
var pipeline = [
{
"$match": {
"participants": ObjectId("5534b2992a104ed914435c98"),
"messages.read" : false,
"messages.from" : { "$ne": ObjectId('5534b2992a104ed914435c98') }
}
},
{
"$project": {
"_id": 0,
"unread_messages": {
"$size": {
"$filter": {
"input": "$messages",
"as": "msg",
"cond": {
"$and": [
{ "$not": [ "$$msg.read" ] },
{ "$ne": ["$$msg.from", ObjectId('5534b2992a104ed914435c98')]}
]
}
}
}
}
}
}
]
db.conversations.aggregate(pipeline)
如果您使用的是不支持上述运算符的驱动程序,请考虑在$size
作为$match
操作后执行下一个管道阶段,以解构messages
数组这样您就可以为每个元素输出文档。
在解构消息上需要使用$unwind
运算符进行进一步过滤,以便只允许那些符合早期条件的消息在管道中进一步处理。
这一操作对于下一个管道阶段是必需的,$match
运算符按指定的标识符表达式对传入文档进行分组,并将$group
累加器表达式应用于每个组,以便您可以获得组中的文档总数。
最后一个阶段使用$sum
运算符通过抑制_id字段来重新整形流中的最终结果文档,并添加一个新字段unread_messages
,用于描述{{1}的消息总数字段值为false。
最终聚合管道如下所示:
read
您可以在Mongoose聚合中使用它,如下所示:
var pipeline = [
{
"$match": {
"participants": ObjectId("5534b2992a104ed914435c98"),
"messages.read" : false,
"messages.from" : { "$ne": ObjectId('5534b2992a104ed914435c98') }
}
},
{
"$unwind": "$messages"
},
{
"$match": {
"participants": ObjectId("5534b2992a104ed914435c98"),
"messages.read" : false,
"messages.from" : { "$ne": ObjectId('5534b2992a104ed914435c98') }
}
},
{
"$group": {
"_id": null,
"count": {
"$sum": 1
}
}
},
{
"$project": {
"_id": 0,
"unread_messages": "$count"
}
}
]
或使用聚合管道构建器:
Conversations.aggregate(pipeline, function (err, res) {
if (err) return handleError(err);
console.log(res); // [ { unread_messages: 34 } ] <-- this is a made up value :-)
});)