Home > Mobile >  Aggregate in MongoDB while keeping fields from latest document
Aggregate in MongoDB while keeping fields from latest document

Time:11-03

I have documents of the types:

{"rule_id": "rule_1", "description": "desc_rule_1_version_1", "version": 1},
{"rule_id": "rule_1", "description": "desc_rule_1_version_2", "version": 2},
{"rule_id": "rule_2", "description": "desc_rule_2_version_1", "version": 1}

I want to find all the rules with the latest version while keeping the remaining fields from documents from the latest version.

So I want the result as:

{"rule_id": "rule_1", "description": "desc_rule_1_version_2", "version": 2},
{"rule_id": "rule_2", "description": "desc_rule_2_version_1", "version": 1}

Please help me out with this.

I tried to do the aggregate but was not able to keep the fields from the latest version document.

CodePudding user response:

Here's one way you could it if "$top" is available (introduced in MongoDB server version 5.2). If "$top" in unavailable, see below.

db.collection.aggregate([
  {
    "$group": {
      "_id": "$rule_id",
      "latest": {
        "$top": {
          "sortBy": {
            "version": -1
          },
          "output": "$$ROOT"
        }
      }
    }
  },
  {
    "$replaceWith": "$latest"
  }
])

Try it on mongoplayground.net.

If "$top" is unavailable, here's another way you could do it.

db.collection.aggregate([
  {
    "$group": {
      "_id": "$rule_id",
      "docs": {"$push": "$$ROOT"},
      "latestVersion": {"$max": "$version"}
    }
  },
  {
    "$project": {
      "latest": {
        "$first": {
          "$filter": {
            "input": "$docs",
            "as": "doc",
            "cond": {"$eq": ["$$doc.version", "$latestVersion"]}
          }
        }
      }
    }
  },
  {"$replaceWith": "$latest"}
])

Try it on mongoplayground.net.

  • Related