2016-02-05 68 views
1

我有一个对话集,看起来像这样:MongoDB中找到最大的文件日期和校验值

[ 
    { 
    "_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" 
     } 
    ] 
    } 
] 

每个会话(文件)可以与idlastMessagelastVisited属性的参与者对象。

有时,根据对话的新增情况,这些值中的某些值尚不存在(例如lastMessage,lastVisited)。

我想要做的是比较每个参与者在每个单独的对话(文档),看看是否在所有参与者中,最大的lastMessage字段值属于登录用户。否则,我假设对话中有登录用户尚未看到的消息。我想获得用户可能还没有看到的那些消息。

在上面的例子中,假设我们登录为d3y7uSA2aKCQfLySw。我们可以看到他是发送消息进行对话的最后一个人1,2但是不是3。关于d3y7uSA2aKCQfLySw还没有看到多少更新对话的计数返回应该是1.

有人能指出我正确的方向吗?对于如何解决这个问题,我丝毫没有丝毫的线索。我对这个冗长的问题表示歉意。

回答

1

总是建议将日期存储为ISODate而不是字符串,以利用aggregation框架中各个date operators提供的灵活性。得到计数

的一种方法是,

  • $match用户在其中参与的谈话。
  • $unwindparticipants字段。
  • $sortlastMessage场由_id降序排列
  • $group使用$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"} 
} 
]) 
+0

感谢这个答案,它做我在找什么。问题是,这样的事情可以没有聚合?我使用MeteorJS,对我来说最重要的事情就是一切都在实时工作(反应式)。不幸的是[这个](https://atmospherejs.com/meteorhacks/aggregate)包使我能够使用聚合限制反应性。 – SeanWM

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

我都采用了这种功能,只是返回计数,但是当你看到它很容易调整它返回所有看不见的消息的元数据了。