简体   繁体   English

Mongodb:按数组最后一个元素中的值对文档进行排序

[英]Mongodb: sort documents by value in the last element of an array

I have a collection ' collectionName ' with many documents like these:我有一个集合“ collectionName ”,其中包含许多此类文档:

{
    "_id" : ObjectId("5f072d45856bc306147c1dcd"),
    "readOnly" : false,
    "participants" : [ 
        {
            "clientType" : "support",
            "docId" : "",
            "metaData" : {
                "fullName" : "Support",
                "email" : "Support@mydomain.com",
                "phoneNum" : "+1234567890"
            }
        }, 
        {
            "clientType" : "worker",
            "docId" : "5e21c48ee178473be81e032e",
            "metaData" : {
                "fullName" : "Rami",
                "email" : "myemail@gmail.com",
                "phoneNum" : "+1234567890"
            }
        }
    ],
    "messages" : [ 
        {
            "id" : "IGK-fIt-2zz",
            "sender" : "support, ",
            "body" : "CONTROL: Agent \"Greendizeriii\" has answered the conversation",
            "commData" : {
                "sent" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-11T06:33:48.348Z")
                },
                "delivered" : {
                    "state" : false
                },
                "seen" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-11T06:40:06.851Z")
                }
            }
        }, 
        {
            "id" : "L0f-hwj-QUL",
            "sender" : "support, ",
            "body" : "Hello rami, How can I help you today",
            "commData" : {
                "sent" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-11T06:35:57.406Z")
                },
                "delivered" : {
                    "state" : false
                },
                "seen" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-11T06:40:06.851Z")
                }
            }
        }, 
        {
            "id" : "n0k-s3u-UmN",
            "sender" : "support, ",
            "body" : "are you still there ?",
            "commData" : {
                "sent" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-11T06:36:13.350Z")
                },
                "delivered" : {
                    "state" : false
                },
                "seen" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-11T06:40:06.851Z")
                }
            }
        }
    ],
    "controlData" : {
        "isReserved" : {
            "state" : false,
            "reservedUntil" : null,
            "operatorId" : null
        }
    },
    "__v" : 0
},
{
    "_id" : ObjectId("5f1f143f4134643044638902"),
    "readOnly" : false,
    "participants" : [ 
        {
            "clientType" : "support",
            "docId" : "",
            "metaData" : {
                "fullName" : "Support",
                "email" : "Support@mydomain.com",
                "phoneNum" : "+1234567890"
            }
        }, 
        {
            "clientType" : "worker",
            "docId" : "5ea9409ff3243f483c2483ed",
            "metaData" : {
                "fullName" : "Ronaldo",
                "email" : "dummyemail02@gmail.com",
                "phoneNum" : "+1234567890"
            }
        }
    ],
    "messages" : [ 
        {
            "id" : "uto-qQb-0cr",
            "sender" : "support, ",
            "body" : "CONTROL: Agent \"Greendizeriii\" has answered the conversation",
            "commData" : {
                "sent" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-27T17:51:59.753Z")
                },
                "delivered" : {
                    "state" : false
                },
                "seen" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-27T17:52:01.240Z")
                }
            }
        }, 
        {
            "id" : "FQg-fSQ-jQ1",
            "sender" : "support, ",
            "body" : "jjj",
            "commData" : {
                "sent" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-27T17:51:59.751Z")
                },
                "delivered" : {
                    "state" : false
                },
                "seen" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-27T17:52:01.240Z")
                }
            }
        }, 
        {
            "id" : "Uqm-J4S-LUT",
            "sender" : "support, ",
            "body" : "CONTROL: Agent \"Greendizeriii\" has left the conversation",
            "commData" : {
                "sent" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-27T17:53:05.142Z")
                },
                "delivered" : {
                    "state" : false
                },
                "seen" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-27T17:53:05.558Z")
                }
            }
        }, 
        {
            "id" : "gs1-Qqz-jkI",
            "sender" : "worker, 5ea9409ff3243f483c2483ed",
            "body" : "Hello",
            "commData" : {
                "sent" : {
                    "state" : true,
                    "dateTime" : ISODate("2020-07-25T03:58:50.600Z")
                },
                "delivered" : {
                    "state" : false
                },
                "seen" : {
                    "state" : false
                }
            }
        }
    ],
    "controlData" : {
        "isReserved" : {
            "state" : false,
            "reservedUntil" : null,
            "operatorId" : null
        }
    },
    "__v" : 0
}

for example here are two documents例如这里有两个文件

each one has messages field which is an array of elements/objects每个都有消息字段,它是一个元素/对象数组

I want to sort them using ( commData.sent.dateTime ) of the latest element of messages array.我想使用消息数组的最新元素( commData.sent.dateTime )对它们进行排序。

I know I can do something like:我知道我可以做类似的事情:

db.getCollection('collectionName').find({}).sort({"messages.0.commData.sent.dateTime": 1})

which will return documents sorted using the commData.sent.dateTime of first element in messages array.这将返回使用 messages 数组中第一个元素的 commData.sent.dateTime 排序的文档。 but I don't know how to sort using the last element in the array in this particular situation.但我不知道如何在这种特定情况下使用数组中的最后一个元素进行排序。

Note: The answer for question: How to sort a collection using the last element of an array will not work in my case since the field (dateTime) I need to use to sort the documents is inside a nested object注意:问题的答案: How to sorting a collection using the last element of an array will not work in my case 因为我需要用来对文档进行排序的字段 (dateTime) 位于嵌套的 object 中

your help is so appreciated.非常感谢您的帮助。

Thank you谢谢

You can use $addFields to calculate last sent date.您可以使用$addFields来计算上次发送日期。 $arrayElemAt takes -1 as a parameter which represents the last item of an array: $arrayElemAt-1作为参数,表示数组的最后一项:

db.collection.aggregate([
    {
        $addFields: {
            lastSent: {
                $let: {
                    vars: {
                        last: {
                            $arrayElemAt: [ "$messages", -1 ]
                        }
                    },
                    in: "$$last.commData.sent.dateTime"
                }
            }
        }
    },
    { $sort: { lastSent: 1 } },
    { $project: { lastSent: 0 } }
])

Mongo Playground蒙戈游乐场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM