我有一个Conversation集合,如下所示:
[
{
"_id": "QzuTQYkGDBkgGnHrZ",
"participants": [
{
"id": "YymyFZ27NKtuLyP2C"
},
{
"id": "d3y7uSA2aKCQfLySw",
"lastVisited": "2016-02-04T02:59:10.056Z",
"lastMessage": "2016-02-04T02:59:10.056Z"
}
]
},
{
"_id": "e4iRefrkqrhnokH7Y",
"participants": [
{
"id": "d3y7uSA2aKCQfLySw",
"lastVisited": "2016-02-04T03:26:33.953Z",
"lastMessage": "2016-02-04T03:26:53.509Z"
},
{
"id": "SRobpwtjBANPe9hXg",
"lastVisited": "2016-02-04T03:26:35.210Z",
"lastMessage": "2016-02-04T03:15:05.779Z"
}
]
},
{
"_id": "twXPHb76MMxQ3MQor",
"participants": [
{
"id": "d3y7uSA2aKCQfLySw"
},
{
"id": "SRobpwtjBANPe9hXg",
"lastMessage": "2016-02-04T03:27:35.281Z",
"lastVisited": "2016-02-04T03:57:51.036Z"
}
]
}
]
每个会话(文档)都可以有一个参与者对象,其属性为id
,lastMessage
,lastVisited
。
有时,根据对话的新增方式,其中一些值尚不存在(例如lastMessage
,lastVisited
)。
我要做的是比较每个单独会话(文档)中的每个参与者,并查看是否所有参与者中,最大lastMessage
字段值属于登录用户。否则,我假设对话具有登录用户尚未看到的消息。我希望获得用户可能尚未看到的消息数量。
在上面的示例中,假设我们以d3y7uSA2aKCQfLySw
身份登录。我们可以看到他是发送对话消息的最后一个人1
,2
但不是3
。对于d3y7uSA2aKCQfLySw
未见过的更新会话数,返回的计数应为1。
有人能指出我正确的方向吗?关于如何处理这个问题我没有丝毫的线索。我为这个冗长的问题道歉。
答案 0 :(得分:1)
始终建议将日期存储为ISODate
而不是字符串,以利用aggregation
框架中各种date operators
提供的灵活性。
获得计数的一种方法是,
$match
用户参与的对话。$unwind
participants
字段。$sort
由lastMessage
字段按降序排列$group
_id
完整地恢复原始会话,并使用$first
运营商获取每个群组的最新消息(对话)。
$project
值为0
的字段,对于每个组,其中最重要的记录是我们要查找的用户,1
表示其他用户。$group
再次获取他不是最后一个发送消息的会话总数。示例代码:
var userId = "d3y7uSA2aKCQfLySw";
db.t.aggregate([
{
$match:{"participants.id":userId}
},
{
$unwind:"$participants"
},
{
$sort:{"participants.lastMessage":-1}
},
{
$group:{"_id":"$_id","lastParticipant":{$first:"$$ROOT.participants"}}
},
{
$project:{
"hasNotSeen":{$cond:[
{$eq:["$lastParticipant.id",userId]},
0,
1
]},
"_id":0}
},
{
$group:{"_id":null,"count":{$sum:"$hasNotSeen"}}
},
{
$project:{"_id":0,"numberOfConversationsNotSeen":"$count"}
}
])
答案 1 :(得分:0)
我想尝试这个功能。
function findUseen(uId) {
var numMessages = db.demo.aggregate(
[
{
$project: {
"participants.lastMessage": 1,
"participants.id": 1
}
},
{$unwind: "$participants"},
{$sort: {"participants.lastMessage": -1}},
{
$group: {
_id: "$_id",
participantsId: {$first: "$participants.id"},
lastMessage: {$max: "$participants.lastMessage"}
}
},
{$match: {participantsId: {$ne: uId}}},
]
).toArray().length;
return numMessages;
}
调用findUnseen("d3y7uSA2aKCQfLySw")
将返回1.
我已经采用此功能只是为了返回计数,但正如您所见,它很容易调整它以返回所有看不见的消息元数据。