如何在Mongoose的嵌入式文档中检索数组的最后一个对象? [英] How to retrieve an array's last object in an embedded document in Mongoose?

查看:80
本文介绍了如何在Mongoose的嵌入式文档中检索数组的最后一个对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编写查询以检索嵌入在Story文档中的Comments数组的最后一个对象时遇到麻烦.

I have trouble writing the query to retrieve the last object of the Comments array embedded inside the Story document.

当我执行db.stories.find()时,我的收藏集目前看起来像这样:

My collection currently looks like this when I do db.stories.find():

{
"_id" : ObjectId("55d3a39565698bbc68079e31"),
"author" : "Steven Chen",
"link" : "COCO",
"title" : "COCO",
"date" : ISODate("2015-08-18T21:28:53.629Z"),
"comments" : [
    {
        "author" : "Steven",
        "text" : "Major",
        "_id" : ObjectId("55d3a39565698bbc68079e32"),
        "date" : ISODate("2015-08-18T21:28:53.632Z")
    },
    {
        "text" : "Canada",
        "author" : "Steven",
        "_id" : ObjectId("55d3a39a65698bbc68079e33"),
        "date" : ISODate("2015-08-18T21:28:58.001Z")
    },
    {
        "text" : "Usa",
        "author" : "Steven",
        "_id" : ObjectId("55d3a39c65698bbc68079e34"),
        "date" : ISODate("2015-08-18T21:29:00.877Z")
    }
],
"__v" : 0
}

我想根据故事文档_id给出的日期检索最后一条评论.

I want to get retrieve the last comment based on the date given the _id of the Story document.

我的代码的上下文是,有一个带有评论列表的Story帖子,我想检索最近的评论,并使用ajax以JSON的形式将其作为JSON发送到我的客户端JS,因此视图可以用最新的/最新评论.

The context of my code is that there is a Story post with a list of comments and I want to retrieve the last comment and send it to my client JS as a JSON using ajax so the view can be updated with the newest/latest comment.

在这种情况下,带有文本:"Usa"的注释"应该是被检索的注释.

In this case, the comment with "text: "Usa" should be the one getting retrieved.

有人可以提供执行此操作的正确方法吗,如果您可以解释原因,那就更好了?谢谢!

Can someone provide the proper way to do this and it would be even better if you can explain why? Thank you!

推荐答案

您的最新"文档将始终位于数组的末尾,除非您进行某种修改.与 $push 运算符,或在客户端代码中使用数组操作方法添加.

Your "latest" document will always be at the end of your array unless you modify somehow. Adding items into arrays will always go to the "end" or "append" to the existing items when used with the $push operator or added using array manipulation methods in client code.

$addToSet 之类的运算符,或明确使用$push操作的修饰符将对此进行更改.

Only operators like $addToSet or explicitly using modifiers to the $push operation will change this.

这样,在数组末尾时,通常要使用 $slice ,带有负索引以从数组的末端"获取项目:

As such, when at the end of an array, what you typically want to do is use $slice, with a negative index to get items from the "end" of the array:

Model.findById("55d3a39565698bbc68079e31")
    .select({ "comments": { "$slice": -1 }})
    .exec(function(err,doc) {

    })

如果您实际上已经按照前面提到的那样修改了数组,而最新日期不是数组中的最后一个元素,那么您应该使用$position是有意的,您不能同时进行排序,但是您始终可以在这样的$addToSet操作之后对数组进行排序,该操作将所有日期按顺序排列,而不会更改数组的任何其他内容:

If you have actually modfied the array as mentioned earlier where the latest date is not the last element in the array then you should be using the $sort modifier on updates. It would generally only be "out of place" if you asked for the $position modifier or you used $addToSet. The $position would be deliberate and you cannot also sort, but you can always sort the array after an $addToSet operation like this, which places the alls the dates in order without changing any other content of the array:

Model.findByIdAndUpdate("55d3a39565698bbc68079e31",
   { "$push": { "comments": { "$each": [], "$sort": { "date": 1 } } } }
)

修改数组后,由于数组按日期顺序排列,因此对查询执行相同的$slice操作.

With the array modified the same $slice operation applies to queries as the array is now in the order by date.

但是,如果您的意图是使文档中的数组不按顺序排列,或按您想要的其他顺序排列,但又想获取最新日期,则可以使用 $sort 并检索/ $last 数组条目:

If however your intention is leave the array in your documents out of order, or in the other order you want, but you also want to get the latest date, then you can use .aggregate() to $sort and retrieve the $last array entry:

Model.aggregate(
    [
        { "$match": { "_id": ObjectID("55d3a39565698bbc68079e31") } },
        { "$unwind": "$comments" },
        { "$sort": { "comments.date": 1 } },
        { "$group": {
            "_id": "$_id",
            "author": { "$first": "$author" },
            "link": { "$first": "$link" },
            "title": { "$first": "$title" },
            "date": { "$first": "$date" },
            "comments": { "$last": "$comments" }
        }}
    ]
)

请注意,当将聚合框架与猫鼬一起使用时,在其他查询中发生的_id自动广播"不会发生(这是设计使然),因此如果需要,必须自己转换为ObjectId值该数据尚无法以该格式提供,而是以字符串形式输入.

Noting that when using the aggregation framework with mongoose, the _id "autocasting" that happens in other queries does not happen ( this is by design ), so it is necessary to cast to an ObjectId value yourself, if the data is not already available in that form and has come in as a string.

这是从数组中获取最后一个元素(可以选择显式排序的元素)的方法.

Those are your ways of getting the last element ( optionally explicitly sorted ) from an array.

这篇关于如何在Mongoose的嵌入式文档中检索数组的最后一个对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆