Search code examples
node.jsmongodbmongoose

How to repeat all fields key and set the new value in $project stage in aggregate mongodb?


I have a schema model with so many fields like below example, I want to clone root field in suggest_foo to $project stage of aggregation without having to manually rewrite those fields and then set those fields with new value as my logic.

Example:

  • schema model:

    const fooSchema = new Schema({
       suggest_foo: 
         foo1: String,
         foo2: String,
         foo3: String,
         foo4: String,
         foo5: String,
       }
       ...
    })
    
  • seeds data:

    {
       suggest_foo: {
         foo1: 'Foo1',
         foo2: 'Foo2',
         foo3: 'Foo3',
         foo4: 'Foo4',
         foo5: 'Foo5',
       }
    }
    
  • aggregate query code:

    fooSchema.aggregate([
       ...
       {
         $project: {
            // I want to clone root in suggest_foo (eg: foo1, foo2, foo(n)...) to be here.
         }
       }
    ])
    

My output result that I expected look like:

  {
     foo1: 'Foo1 maybe you like',
     foo2: 'Foo2 maybe you like',
     foo3: 'Foo3 maybe you like',
     foo4: 'Foo4 maybe you like',
     foo5: 'Foo5 maybe you like',
  }

Solution

  • One option is to use $replaceRoot with $arrayToObject and $objectToArray as this will allow you to manipulate array in a loop:

    db.collection.aggregate([
      {$replaceRoot: {
          newRoot: {
            $arrayToObject: {
              $map: {
                input: {$objectToArray: "$suggest_foo"},
                in: {
                  v: {$concat: ["$$this.v", " maybe you like"]},
                  k: "$$this.k"
                }
              }
            }
          }
      }}
    ])
    

    See how it works on the playground example