Home > database >  Mongodb aggregation for object replacement in case of dynamic keys
Mongodb aggregation for object replacement in case of dynamic keys

Time:05-29

Let's say I have a following collection with _id and traits.

{
  _id: 1,
  traits: {
    Rarity: {
      infoin: 15,
    },
    Type: {
      iron: 3,
      sliver: 5,
      wood: 7,
    },
  },
},
{
  _id: 2,
  traits: {
    Cloth: {
      barron1: 11,
      barron2: 12,
    },
    Hair: {
      black: 6,
      yellow: 9,
      red: 8
    }
  },
},
...

As you can see keys of traits are dynamic and keys of sub objects as well.

Here is the result I wanna get:

{
  _id: 1,
  traits: 15,
},
{
  _id: 2,
  traits: 23
}

Tip:

infocoin = iron sliver wood

barron1 barron2 = black yellow red

CodePudding user response:

  1. $set - Set traitObjs array field by converting the object to array via $objectToArray.

  2. $set - Set firstTraitValues field by getting the value of first document from traitObjs array, then converting from object to array via $objectToArray.

  3. $project - Decorate the output document. Set traits field by converting firstTraitValues array to number type with $reduce and $sum all the v values.

db.collection.aggregate([
  {
    $set: {
      traitObjs: {
        $objectToArray: "$traits"
      }
    }
  },
  {
    $set: {
      firstTraitValues: {
        $objectToArray: {
          $first: "$traitObjs.v"
        }
      }
    }
  },
  {
    $project: {
      traits: {
        $reduce: {
          input: "$firstTraitValues",
          initialValue: 0,
          in: {
            $sum: [
              "$$value",
              "$$this.v"
            ]
          }
        }
      }
    }
  }
])

Sample Mongo Playground


Since all the values in the first key document and the second key document of traits are the same,

infocoin = iron sliver wood

barron1 barron2 = black yellow red

Hence the above approach just sums up all the values in the first key document of traits.

  • Related