0

I have an existing document and I wish to add a unique Object Id to each of the transaction Array Objects.

{
_id: ObjectId(6086d7e7e39add6a5220d0a5),
firstName: "John"
lastName: "Doe"
transactions: [
  {
    date: 2022-04-12T09:00:00.000+00:00
    amount: 286.56
    type: "deposit"
    method: "Bank transfer"
  },
  {
    date: 2022-04-15T09:00:00.000+00:00
    amount: 120.23
    type: "withdrawal"
    method: "cash"
  }]
}

The outcome would be each transactions Object would have a unique ObjectId. I have tried the following query but it add the same ObjectId to all objects:

collection.updateMany({}, [
  {
    $set: {
      transactions: {
        $map: {
          input: "$transactions",
          in: {
            $mergeObjects: ["$$this", { _id: new mongo.ObjectId() }],
          },
        },
      },
    },
  },
]);

Can anyone see why I am getting the same ObjectId written to all of the Objects in the transactions array instead of unique Ids?

Phil Glen
  • 24
  • 7
  • question is very similar to [this](https://stackoverflow.com/questions/70028674/how-to-generate-a-unique-objectid-inside-an-update-or-aggregation/70029031) – Takis Apr 30 '22 at 10:54

2 Answers2

1

The code new mongo.ObjectId() will run on the driver => 1 id for all.
You need the js to run on the server, one time for each member.

Try to replace the new mongo.ObjectId() with the bellow $function code that will run on the server.
In general we should avoid javascript, but i don't think we have an aggregate operator that generates ObjectId's.

Another alternative is to write all the $map function in javascript, again with the use of $function.

*$function requires MongoDB >=4.4

{
  "$function": {
    "body": "function () {return new ObjectId();}",
    "args": [],
    "lang": "js"
  }
}
Takis
  • 8,314
  • 2
  • 14
  • 25
  • Unfortunately, though I am using Mongo v5.0 it's on a free Atlas cluster which does not allow server side JavaScript. – Phil Glen May 02 '22 at 12:09
1

the _id field in a document cannot be modified.in fact you are tying to modify main objectid. try another name for your transaction_id field.

  • Could I use an ObjectId or should I generate a random number with Math.random() Or even better just increment by 1 for each object would be sufficient, I just need a way of identifying the object from another collection. – Phil Glen May 02 '22 at 12:11
  • there is a trick like adding a number to end of main object id .it helps readability or other usages in the future that probably you dont know about right now.but since your purpose is only making a unique value as you said , then dont spend time to engineering a small feature. just use math.random and go to next step. – Meelad Ghazipour May 02 '22 at 22:08
  • by the way math.random is math.random. its not math.unique ... ! – Meelad Ghazipour May 02 '22 at 22:09