sdot257
sdot257

Reputation: 10376

Return latest record from subdocument in Mongodb

Let's say i want to return the latest inserted document from the subdocument. I want to be able to return the second record within the tags array w/ the _id of 54a1845def7572cd0e3fe288

So I far I have this query but it returns all values in the tags array.

db.modules.findOne({_id:"ui","svn_branches.branch":"Rocky"},{"svn_branches.$":1})

Mongodb array:

{
"_id" : "ui",
"svn_branches" : [ 
    {
        "updated_at" : ISODate("2013-06-12T20:48:17.297Z"),
        "branch" : "Rocky",
        "revision" : 0,
        "tags" : [ 
            {
                "_id" : ObjectId("54a178b8ef7572d30e3fe288"),
                "commit_message" : "r277 | ssmith | 2015-02-11 17:43:23 -0400 (Wed, 11 Feb 2015)",
                "latest_tag" : "20150218r1_6.32_abc",
                "revision" : 1,
                "tag_revision_number" : "280",
                "updated_at" : ISODate("2015-02-18T19:54:54.062Z")
            }, 
            {
                "_id" : ObjectId("54a1845def7572cd0e3fe288"),
                "commit_message" : "r271 | sam | 2dskjh\n",
                "latest_tag" : "20150218r2_6.32_abc",
                "revision" : 2,
                "tag_revision_number" : "281",
                "updated_at" : ISODate("2015-02-19T19:54:54.062Z")
            }
        ]
    }
]
}

Upvotes: 1

Views: 2130

Answers (3)

WasiF
WasiF

Reputation: 28939

Simple Solution

Let say we have a category as a document and items as a subdocument.

// find document from collection
const category = await Category.findOne({ _id:'$hec453d235xhHe4Y' });

// fetch last index of sub-document
const lastItemIndex = category.items.length - 1;
        
// here is the last item of sub-document
console.log(category.items[lastItemIndex]);

as mongodb inserted the latest sub-document at last index, so we need to find the last index for the latest sub-doc.

Upvotes: 3

Atika
Atika

Reputation: 1618

I needed to find the last entry of subdocuments and I managed to make it to work with the $slice projection operator: mondodb.com > $slice (projection)

db.modules.find({_id:'ui', 'svn_branches.branch':'Rocky'}, 
                { 'svn_branches.tags': {$slice:-1} } )

I had only one level, if this doesn't work, please let me know.

Upvotes: 2

wdberkeley
wdberkeley

Reputation: 11671

Queries in MongoDB do not return subdocuments (or, as in your case, subdocuments of subdocuments). They match and return the the documents in the collection. The documents' shape can be changed a bit by projection, but it's limited. If you want to find the latest tag commonly, you probably want to make your documents represent tags. Having an array in an array is generally a bad idea in MongoDB, too.

If this is an uncommon operation, and one that doesn't need to be particularly fast, you can use an aggregation:

db.modules.aggregate([
    { "$unwind" : "$svn_branches" },
    { "$unwind" : "$svn_branches.tags" },
    { "$sort" : { "svn_branches.tags.updated_at" : -1 } },
    { "$group" : { "_id" : "$_id", "latest_tag" : { "$first" : "$svn_branches.tags" } } }
])

Upvotes: 2

Related Questions