Home > Blockchain >  How do I the merge the results of a facet into a list, with conditions, in mongodb?
How do I the merge the results of a facet into a list, with conditions, in mongodb?

Time:01-18

I have a facet with the following result:

{
    directConfigs: [
        type: "Type A",
        result: {
            priority: 2,
            id: ObjectId('63c6a4b858612f44f37d4771')
        },
        type: "Type B",
        result: {
            priority: 3,
            id: ObjectId('63bd7878f1f085f7d8a6827f')
        }
    ],
    indirectConfigs: [
        type: "Type A",
        result: {
            priority: 1,
            id: ObjectId('627279d3ba7aef5d6418c867')
        },
        type: "Type C",
        result: {
            priority: 5,
            id: ObjectId('63be730bf1f085f7d8a682c8')
        }
    ],
}

From this result I want to get a list of objects grouped on the type field. The rules are that directConfigs have priority over indirectConfigs. So if both arrays have a Type A config, we want the one in directConfigs. I've already made sure that each of the types can only occur once in each of the arrays. The result should look like this:

result: [
    {
        type: "Type A",
        result: {
            priority: 2,
            id: ObjectId('63c6a4b858612f44f37d4771')
        }
    },
    {
        type: "Type B",
        result: {
            priority: 3,
            id: ObjectId('63bd7878f1f085f7d8a6827f')
        }
    },
    {
        type: "Type C",
        result: {
            priority: 5,
            id: ObjectId('63be730bf1f085f7d8a682c8')
        }
    }
]

How do I do that?

CodePudding user response:

One option is to use $reduce:

db.collection.aggregate([
  {$project: {
      _id: 0,
      result: {
        $reduce: {
          input: "$indirectConfigs",
          initialValue: "$directConfigs",
          in: {$concatArrays: [
              "$$value",
              {$cond: [
                  {$not: {$in: ["$$this.type", "$$value.type"]}},
                  ["$$this"],
                  []
              ]}
          ]}
        }
      }
  }}
])

See how it works on the playground example

  • Related