【问题标题】:Mongodb: sort documents by value in the last element of an arrayMongodb:按数组最后一个元素中的值对文档进行排序
【发布时间】:2020-11-18 06:33:38
【问题描述】:

我有一个集合“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
}

例如这里有两个文档

每个都有 messages 字段,这是一个元素/对象数组

我想使用消息数组的最新元素 (commData.sent.dateTime) 对它们进行排序。

我知道我可以这样做:

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

这将返回使用消息数组中第一个元素的 commData.sent.dateTime 排序的文档。但我不知道在这种特殊情况下如何使用数组中的最后一个元素进行排序。

注意: 问题答案:How to sort a collection using the last element of an array 在我的情况下不起作用,因为我需要用来对文档进行排序的字段 (dateTime) 位于嵌套对象内

非常感谢您的帮助。

谢谢

【问题讨论】:

标签: node.js mongodb sorting mongoose mongodb-query


【解决方案1】:

您可以使用$addFields 计算上次发送日期。 $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

【讨论】:

  • 非常感谢@mickl ????✨ 我找这个已经快一周了。我编辑了答案并在 $sort 之后添加了一个 $projection 阶段,以从输出中删除 lastSent 字段,因为它不再需要。
  • @mickl 如果我想获得与特定过滤器匹配的最后一个对象。我该如何使用它?例如,具有特定“发件人”的最后一条消息。
  • @letie 请打开一个单独的问题
  • @mickl 我创建了这个问题:stackoverflow.com/questions/65831571/…
猜你喜欢
  • 2015-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多