有2个用于处理聊天的集合
chatRooms的示例数据如下
{
"data": [
{
"_id": "5a606ab0116e2c164b25ef33",
"topic": "akhil Ben chat",
"topicDesc": "question 1",
"roomName": "benakhil777akhil",
"createdOn": "2018-01-18T09:36:48.231Z",
"participants": [
"ben",
"akhil777"
],
"__v": 0
},
{
"_id": "5a4dbdaab46b426863e7ead3",
"topic": "test",
"topicDesc": "test123",
"roomName": "benakhil777test",
"createdOn": "2018-01-04T05:37:46.088Z",
"participants": [
"ben",
"akhil777"
],
"__v": 0
}
]}
chatMessages的示例数据如下
{"data": [
{
"_id": "5a62281ea0652120a6668bae",
"topic": "akhil Ben chat",
"roomName": "benakhil777akhil",
"message": "test 1",
"__v": 0,
"readStatus": [
{
"recipient": "ben",
"_id": "5a62281ea0652120a6668bb0",
"status": true
},
{
"recipient": "akhil777",
"_id": "5a62281ea0652120a6668baf",
"status": true
}
],
"createdOn": "2018-01-19T17:17:18.456Z"
},
{
"_id": "5a622866a0652120a6668bb1",
"topic": "akhil Ben chat",
"roomName": "benakhil777akhil",
"message": "Test 2",
"__v": 0,
"readStatus": [
{
"recipient": "ben",
"_id": "5a622866a0652120a6668bb3",
"status": false
},
{
"recipient": "akhil777",
"_id": "5a622866a0652120a6668bb2",
"status": true
}
],
"createdOn": "2018-01-19T17:18:30.396Z"
},
{
"_id": "5a62287ca0652120a6668bb4",
"topic": "akhil Ben chat",
"roomName": "benakhil777akhil",
"message": "test 3",
"__v": 0,
"readStatus": [
{
"recipient": "ben",
"_id": "5a62287ca0652120a6668bb6",
"status": false
},
{
"recipient": "akhil777",
"_id": "5a62287ca0652120a6668bb5",
"status": true
}
],
"createdOn": "2018-01-19T17:18:52.018Z"
}
]}
在上面的JSON readStatus存储状态中,用户是否读取了消息。这样我就可以为每个聊天室计算用户的未读消息。 readStatus中的状态保存消息的读取状态,读取消息时为true。 有两个房间 benakhil777akhil 和 benakhil777test 。
我想得到的是用户说每个房间的未读消息数 ben
还有userDetails集合 比方说,
[{
"_id": "59e6d6ba02e11e1814481022",
"username": "ben",
"name": "Ben S",
"email": "qwerty@123.com",
},{
"_id": "59e6d6ba02e11e1814481022",
"username": "akhil777",
"name": "Akhil Clement",
"email": "qwerty@123.com",
}]
这将是用户详细信息集合
并输出我需要的JSON就像。
{
"data": [
{
"_id": "5a606ab0116e2c164b25ef33",
"topic": "akhil Ben chat",
"topicDesc": "question 1",
"roomName": "benakhil777akhil",
"createdOn": "2018-01-18T09:36:48.231Z",
"participants": [
"ben",
"akhil777"
],
"participantDetails":[{
"_id": "59e6d6ba02e11e1814481022",
"username": "ben",
"name": "Ben S",
"email": "qwerty@123.com",
},{
"_id": "59e6d6ba02e11e1814481022",
"username": "akhil777",
"name": "Akhil Clement",
"email": "qwerty@123.com",
}],
"unreadCount": 2,
"__v": 0
},
{
"_id": "5a4dbdaab46b426863e7ead3",
"topic": "test",
"topicDesc": "test123",
"roomName": "benakhil777test",
"createdOn": "2018-01-04T05:37:46.088Z",
"participants": [
"ben",
"akhil777"
],
"participantDetails":[{
"_id": "59e6d6ba02e11e1814481022",
"username": "ben",
"name": "Ben S",
"email": "qwerty@123.com",
},{
"_id": "59e6d6ba02e11e1814481022",
"username": "akhil777",
"name": "Akhil Clement",
"email": "qwerty@123.com",
}],
"unreadCount": 0,
"__v": 0
}
]}
答案 0 :(得分:1)
请尝试此聚合管道
db.rooms.aggregate(
[
{$match : {participants : 'ben'}},
{$lookup : {
from : "chats",
localField : "roomName",
foreignField:"roomName",
as :"out"
}
},
{$unwind : {
path: "$out",
preserveNullAndEmptyArrays: true
}
},
{$unwind : {
path: "$out.readStatus",
preserveNullAndEmptyArrays: true
}
},
{$addFields : {
isMatch : { $and : [
{ $eq : ["$out.readStatus.recipient" , "ben" ] } , { $eq : [ "$out.readStatus.status" , false ] } ]
}
}
},
{$group : {
_id : {
_id : "$_id" ,
topic : "$topic",
topicDesc : "$topicDesc",
createdOn : "$createdOn",
participants : "$participants",
roomName : "$roomName"
},
unreadCount : { $sum : { $cond : [ "$isMatch" , 1, 0 ] } }
}
},
{$sort : {unreadCount : -1}}
]
).pretty()
结果
{
"_id" : {
"_id" : "5a606ab0116e2c164b25ef33",
"topic" : "akhil Ben chat",
"topicDesc" : "question 1",
"createdOn" : "2018-01-18T09:36:48.231Z",
"participants" : [
"ben",
"akhil777"
],
"roomName" : "benakhil777akhil"
},
"unreadCount" : 2
}
{
"_id" : {
"_id" : "5a4dbdaab46b426863e7ead3",
"topic" : "test",
"topicDesc" : "test123",
"createdOn" : "2018-01-04T05:37:46.088Z",
"participants" : [
"ben",
"akhil777"
],
"roomName" : "benakhil777test"
},
"unreadCount" : 0
}
编辑,因为addFields
在3.2.17
{$group : {
_id : {
_id : "$_id" ,
topic : "$topic",
topicDesc : "$topicDesc",
createdOn : "$createdOn",
participants : "$participants",
roomName : "$roomName"
},
unreadCount : { $sum : { $cond : [ { $and : [
{ $eq : ["$out.readStatus.recipient" , "ben" ] } , { $eq : [ "$out.readStatus.status" , false ] } ]
} , 1, 0 ] } }
}
}
EDIT-2 添加了$project
{$project :
{
"_id" : "$_id._id",
"topic" : "$_id.topic",
"topicDesc" : "$_id.topicDesc",
"createdOn" : "$_id.createdOn",
"participants" : "$_id.participants",
"roomName" : "$_id.roomName",
"unreadCount" : "$unreadCount"
}
}
答案 1 :(得分:1)
您可以简化代码以便在聚合下使用。
带有输入条件的 $cond
用于检查读状态标志,当为真时输出1为0。
内部$sum
使用外部$ sum计算每条聊天消息中的未读值,以便对所有匹配的聊天消息中的未读值进行求和。
db.chatRooms.aggregate(
[{
"$match":{"participants":"ben"}},
{"$lookup":{
"from":"chatMessages",
"localField":"roomName",
"foreignField":"roomName",
"as":"chatMessages"
}},
{"$project":{
"topic":1,
"topicDesc":1,
"roomName":1,
"createdOn":1,
"participants":1,
"unreadCount":{
"$sum":{
"$map":{
"input":"$chatMessages",
"as":"chatMessage",
"in":{
"$sum":{
"$map":{
"input":"$$chatMessage.readStatus",
"as":"mChatMessage",
"in":{"$cond":[{"$eq":["$$mChatMessage.status",false]},1,0]}
}
}
}
}
}
}
}}
])
答案 2 :(得分:0)
结果JSON包含用户详细信息。
db.chatRooms.aggregate(
[
{$match : {participants : 'ben'}},
{ $unwind : {
path: "$participants",
preserveNullAndEmptyArrays: true
}
},
{ $lookup: {
from:"users",
localField:"participants",
foreignField:"username",
as:"userData"
}
},
{ $lookup: {
from:"chatmessages",
localField:"roomName",
foreignField:"roomName",
as:"out"
}
},
{ $unwind : {
path: "$out",
preserveNullAndEmptyArrays: true
}
},
{ $unwind : {
path: "$out.readStatus",
preserveNullAndEmptyArrays: true
}
},
{ $group : {
_id : {
_id : "$_id" ,
topic : "$topic",
topicDesc : "$topicDesc",
createdOn : "$createdOn",
roomName : "$roomName"
},
participants : {$addToSet : "$participants" } ,
participantDetails : {$addToSet : {$arrayElemAt : ["$userData", 0]}},
unreadCount : {
$sum : {
$cond : [ {
$and : [
{ $eq : ["$out.readStatus.recipient" , "ben" ] } ,
{ $eq : [ "$out.readStatus.status" , false ] }
]
} , 1, 0
]
}
}
}
}
,
{ $project :
{
_id : "$_id._id",
topic : "$_id.topic",
topicDesc : "$_id.topicDesc",
createdOn : "$_id.createdOn",
participants : "$_id.participants",
roomName : "$_id.roomName",
unreadCount : "$unreadCount",
participants : 1 ,
participantDetails : 1
}
}
])