Home > Enterprise >  Projecting data after doing a $facet
Projecting data after doing a $facet

Time:09-30

After doing a $facet I receive this output:

[
    {
        "confirmed": [
            {
                "confirmed": 100
            }
        ],
        "denied": [
            {
                "denied": 50
            }
        ],
        "pending": [
            {
                "pending": 20
            }
        ]
    }
]

how can I project it into something like this?

[
    {
        category: "confirmed", count: 100,
        category: "denied", count: 50,
        category: "pending", count: 20
    }
]

I need the faucet part because to extract those numbers I have to do several $match to the same data. Dont know if there is a better option.

Thank you!

CodePudding user response:

What you ask is not a valid format. This is an object with duplicate keys. You may want:

[{"confirmed": 100,  "denied": 50, "pending": 20}]

or

[
  {category: "confirmed", count: 100}, 
  {category: "denied", count: 50}, 
  {category: "pending", count: 20}
]

which are both valid options

I guess you want the second option. If you want the generic solution, one option is:

db.collection.aggregate([
  {$project: {res: {$objectToArray: "$$ROOT"}}},
  {$project: {
      res: {$map: {
          input: "$res",
          in: {category: "$$this.k", count: {$objectToArray: {$first: "$$this.v"}}}
      }}
  }},
  {$project: {
      res: {$map: {
          input: "$res",
          in: {category: "$$this.category", count: {$first: "$$this.count.v"}}
      }}
  }},
  {$unwind: "$res"},
  {$replaceRoot: {newRoot: "$res"}}
])

See how it works on the playground example - generic

If you want the literal option, just use:

db.collection.aggregate([
  {$project: {
      res: [
        {category: "confirmed", count: {$first: "$confirmed.confirmed"}},
        {category: "denied", count: {$first: "$denied.denied"}},
        {category: "pending", count: {$first: "$pending.pending"}}
      ]
    }
  },
  {$unwind: "$res"},
  {$replaceRoot: {newRoot: "$res"}}
])

See how it works on the playground example - literal

  • Related