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

查看:20
本文介绍了如何在 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
}

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

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

我的代码的上下文是有一个带有评论列表的 Story 帖子,我想检索最后一条评论并将其作为使用 ajax 的 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.

在这种情况下,应该检索到带有text: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<这样的操作符/a> 或显式使用 $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) {

    })

如果您确实像前面提到的那样修改了数组,其中最新日期不是数组中的最后一个元素,那么您应该使用 $sort 更新修饰符.如果您要求使用 $position 修饰符或使用 $addToSet,它通常只会不合适".$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.

但是,如果您的意图是将文档中的数组保留为乱序,或以您想要的其他顺序,但您还想获得最新日期,那么您可以使用 .aggregate()$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" }
        }}
    ]
)

注意,当使用聚合框架与 mongoose 时,在其他查询中发生的 _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天全站免登陆