首页 > 解决方案 > 如何查找在某个日期范围内发送的前 3 个文档?

问题描述

我使用 MongoDB 来存储用户消息。通过使用聚合框架,我想根据日期过滤消息并找到回复计数最高的前 3 条消息。

对于许多用户,我有以下 JSON 结构:

[
  {
    "u_name": "Erdem",
    "details": {
      "messages": [
        {
          "m_type": "text",
          "m_date": 1565208272.547057,
          "m_content": "Sentence",
          "m_replied": 0
        },
        {
          "m_date": 1565208362.439494,
          "m_content": "Another Sentence",
          "m_replied": 50
        }
      ]
    }
  },
  {
    "u_name": "Tolga",
    "details": {
      "messages": [
        {
          "m_type": "text",
          "m_date": 1565201272.547057,
          "m_content": "Sentence",
          "m_replied": 0
        },
        {
          "m_date": 1565208322.439494,
          "m_content": "Another Sentence",
          "m_replied": 14
        }
      ]
    }
  }
]

我尝试了以下聚合来过滤掉指定日期范围内的消息,并找到具有最大 m_replied 计数的前 3 条消息。

db.collection.aggregation(
[                                                                        
  {'$unwind' : "$details.messages" },                                                             

  {'$match': {'$and': [{'details.messages.m_date':{'$gte': 1564949580}},                          
                {'details.messages.m_date':{'$lte': 1664949580}}]}},                                                                                        
  {'$group': {'_id': '$u_name','s_msg': {'$max': '$details.messages.m_replied'}}},  

  {'$project': {'_id': 0,'u_name': '$_id','s_msg': 1}},                   

  {'$sort': {'s_msg': -1}},                           

  {'$limit': 3}                                                                                                                                                                                                   
]
)

但是,此查询不会返回具有最大m_replied条目的消息。有人可以帮我找到正确的查询吗?

标签: mongodbaggregation-frameworkpymongo

解决方案


以下查询可以为您提供预期的输出:

db.collection.aggregate([
    {
        $unwind:"$details.messages"
    },
    {
        $match:{
            "details.messages.m_date":{
                $gte:1564949580,
                $lte:1664949580
            }
        }
    },
    {
        $sort:{
            "details.messages.m_replied":-1
        }
    },
    {
        $limit:3
    },
    {
        $project:{
            "_id":0
        }
    }
]).pretty()

输出:

{
    "u_name" : "Erdem",
    "details" : {
        "messages" : {
            "m_date" : 1565208362.439494,
            "m_content" : "Another Sentence",
            "m_replied" : 50
        }
    }
}
{
    "u_name" : "Tolga",
    "details" : {
        "messages" : {
            "m_date" : 1565208322.439494,
            "m_content" : "Another Sentence",
            "m_replied" : 14
        }
    }
}
{
    "u_name" : "Erdem",
    "details" : {
        "messages" : {
            "m_type" : "text",
            "m_date" : 1565208272.547057,
            "m_content" : "Sentence",
            "m_replied" : 0
        }
    }
}

推荐阅读