按日期排序聚合mongodb

Posted

技术标签:

【中文标题】按日期排序聚合mongodb【英文标题】:Sort by date Aggregation mongodb 【发布时间】:2018-04-25 02:10:00 【问题描述】:

我正在尝试使用聚合按日期对文档进行排序。但我做不到。我的尝试如下。我错过了什么吗?

public static JSONArray get_users_from_db(String botId, String pageId, MongoTemplate mongoTemplate) throws Exception 
        AggregationResults<AgentUserLogs> groupResults = mongoTemplate.aggregate(makeQuery(botId, pageId), "chatuser_log", AgentUserLogs.class);
        List<AgentUserLogs> list = groupResults.getMappedResults();
        JSONArray array = new JSONArray();
        Gson gson = new Gson();
        for (AgentUserLogs obj : list) 
            array.put(new JSONObject(gson.toJson(obj)));
        
        return array;
    

 private static Aggregation makeQuery(String botId, String pageId) 
        return newAggregation(
            match(Criteria.where("bot_id").is(botId).and("page_id").is(pageId)),
            group(Fields.fields().and("first_name", "$meta_data.user_data.first_name").and("last_name", "$meta_data.user_data.last_name").and("profile_pic", "$meta_data.user_data.profile_pic").and("user_id", "$user_id").and("last_message", "$live_agent.last_message").and("last_access_time", "$meta_data.last_access_time")),
            sort(Sort.Direction.DESC, "last_access_time")
        );
    

public class AgentUserLogs 

    private String first_name;
    private String last_name;
    private String profile_pic;
    private String user_id;
    private Instant last_access_time;
    private Object last_message;

    @Override
    public String toString() 
        return "" +
            "first_name='" + first_name + '\'' +
            "last_name='" + last_name + '\'' +
            "profile_pic='" + profile_pic + '\'' +
            "user_id='" + user_id + '\'' +
            "last_access_time='" + last_access_time + '\'' +
            "last_message='" + last_message + '\'' +
            "";
    

示例文档


    "_id" : ObjectId("5a0698755a640c6324a17581"),
    "bot_id" : "1",
    "page_id" : "2039339889632748",
    "user_id" : "1258922750901107"
    "meta_data" : 
        "user_data" : 
            "first_name" : "Januka",
            "last_name" : "Samaranayake",
            "profile_pic" : "https://scontent.xx.fbcdn.net/v/t1.0-1/23172506_1725189057492533_3460235097206138375_n.jpg?oh=5183e7dd4e8ac49a49491055c24696d6&oe=5AA59955",
        ,
    ,
    "live_agent" : 
        "last_message" : 
            "time" : "Sun Nov 12 12:24:53 IST 2017",
            "message" : "hh",
            "status" : "notRead"
        ,
        "thread" : [ 
            
                "from" : "user",
                "time" : "Sat Nov 11 15:23:10 IST 2017",
                "message" : 
                    "message" : "Default",
                    "type" : "init"
                
            , 
            
                "from" : "user",
                "time" : "Sun Nov 12 11:08:55 IST 2017",
                "message" : 
                    "message" : "hi",
                    "type" : "text"
                
            , 
            
                "from" : "agent",
                "time" : "Sun Nov 12 11:38:14 IST 2017",
                "message" : 
                    "message" : "hello",
                    "type" : "text"
                
            , 
            
                "from" : "agent",
                "time" : "Sun Nov 12 11:42:31 IST 2017",
                "message" : 
                    "message" : "hi",
                    "type" : "text"
                
            , 
            
                "from" : "agent",
                "time" : "Sun Nov 12 12:23:31 IST 2017",
                "message" : 
                    "message" : "hi",
                    "type" : "text"
                
            , 
            
                "from" : "user",
                "time" : "Sun Nov 12 12:24:53 IST 2017",
                "message" : 
                    "message" : "hh",
                    "type" : "text"
                
            
        ],
        "connect" : false,
        "status" : "New"
     

【问题讨论】:

您期待什么?这只是要求对字段列表进行“分组”,仅此而已。这些都在_id BTW 下“分组”。所以它是"_id.last_access_time"。但不知何故,我认为这实际上不是你打算做的查询。 我要做的是对具有上述字段和排序结果“last_access_time”的文档进行分组。 您所说的“组”是什么意思?如果您真的打算发生什么,那么按照我给您的正确命名进行排序实际上会起作用。否则,您的实际含义与您认为“组”的实际含义不同。 【参考方案1】:

我认为你的$group$sort 有错误

从您粘贴的示例文档中,我无法确定您的 last_access_time 实际存储在哪里,但从您的模型 (AgentUserLogs) 看来,您已将其与可以在字段 @ 下找到的其余字段一起存储987654324@。 这是您最后一个错误的分组字段:

and("last_access_time", "$meta_data.last_access_time")

我相信你的意思是:

and("last_access_time", "$meta_data.user_data.last_access_time")

然后在您的$sort 中,因为您按它进行分组,这意味着它可以通过_id.last_access_time 访问。因此,您的最后一个排序管道必须如下所示:

sort(Sort.Direction.DESC, "_id.last_access_time")

根据您的代码,您的聚合管道应该如下所示(这只是一个示例):

db.getCollection('yourCollectionName').aggregate([
        $match: 
            "bot_id": "1",
            "page_id": "2039339889632748"
        
    ,
    
        $group: 
            _id: 
                first_name: "$meta_data.user_data.first_name",
                last_name: "$meta_data.user_data.last_name",
                profile_pic: "$meta_data.user_data.profile_pic",
                user_id: "$user_id",
                last_message: "$live_agent.last_message",
                last_access_time: "$meta_data.user_data.last_access_time"
            
        

    ,

    
        $sort: 
            "_id.last_access_time": -1
        
    
])

【讨论】:

以上是关于按日期排序聚合mongodb的主要内容,如果未能解决你的问题,请参考以下文章

在雪花中按日期聚合数据组

MongoDBMongoDB 性能优化 - BI查询聚合

SUM 行、返回计数和按日期排序

当使用$ project,$ frequency和$ group时,Mongoose按日期排序

使用 Spring 数据和 mongoDB 进行日期排序的聚合

如何按热门字段(文本字段)对聚合进行排序?或者是不是有可能按文本字段对聚合进行排序(不使用_term)