mongoDB查找文档最大的日期和检查值

时间:2016-02-05 00:18:00

标签: mongodb meteor

我有一个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"
      }
    ]
  }
]

每个会话(文档)都可以有一个参与者对象,其属性为idlastMessagelastVisited

有时,根据对话的新增方式,其中一些值尚不存在(例如lastMessagelastVisited)。

我要做的是比较每个单独会话(文档)中的每个参与者,并查看是否所有参与者中,最大lastMessage字段值属于登录用户。否则,我假设对话具有登录用户尚未看到的消息。我希望获得用户可能尚未看到的消息数量。

在上面的示例中,假设我们以d3y7uSA2aKCQfLySw身份登录。我们可以看到他是发送对话消息的最后一个人12但不是3。对于d3y7uSA2aKCQfLySw未见过的更新会话数,返回的计数应为1。

有人能指出我正确的方向吗?关于如何处理这个问题我没有丝毫的线索。我为这个冗长的问题道歉。

2 个答案:

答案 0 :(得分:1)

始终建议将日期存储为ISODate而不是字符串,以利用aggregation框架中各种date operators提供的灵活性。

获得计数的一种方法是,

  • $match用户参与的对话。
  • $unwind participants字段。
  • $sortlastMessage字段按降序排列
  • {li} $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.

我已经采用此功能只是为了返回计数,但正如您所见,它很容易调整它以返回所有看不见的消息元数据。