0

Suppose I have two documents in a collection:

[
  {
    "_id": 0,
    "name": "aaaa",
    "phone": 111
  },
  {
    "_id": 1,
    "name": "bbbb",
    "phone": 999
  }
]

I want to run an aggregation pipeline that will merge/wrap/combine ALL the fields into a top-level root object called lead. Without mentioning/hardcoding the field names in the query.

Expected output:

[
  {
    "lead": {
      "_id": 0,
      "name": "aaaa",
      "phone": 111
    }
  },
  {
    "lead": {
      "_id": 1,
      "name": "bbbb",
      "phone": 999
    }
  }
]
Dürrani
  • 950
  • 12
  • 21

2 Answers2

2

Works with $replaceWith stage to replace the input documents with new outputdocuments. To get each (original) document, you need to use the $$ROOT variable.

db.collection.aggregate([
  {
    $replaceWith: {
      "lead": "$$ROOT"
    }
  }
])

Demo @ Mongo Playground

Yong Shun
  • 35,286
  • 4
  • 24
  • 46
  • Can also be achieved with `$project` but I'm not sure which one is efficient/recommend? https://stackoverflow.com/a/75945067/9486457 – Dürrani Apr 06 '23 at 01:11
  • 1
    From my perspective, I think the performance is not much different. This `$replaceWith` is an alternative to `$project` and consider as a *shortcut*. – Yong Shun Apr 06 '23 at 02:53
0

Got some help from this answer and was able to achieve it using $project:

db.collection.aggregate([
  {
    $project: {
      lead: "$$ROOT",
      _id: false
    }
  }
])

Playground link

$$ROOT in MongoDB references the content of this document.

Dürrani
  • 950
  • 12
  • 21