PHP Updates with Aggregation Pipeline NOT WORKING

Hello, I’ve tried use php library update with aggregation but it save as string “$history.202308” instead of db value. But it work when I’m run using command in mongodb terminal.

Below is the code example.

$uri = 'mongodb://localhost:27017/?retryWrites=true&w=majority';
        $client = new \MongoDB\Client($uri);
        $collection = $client->selectDatabase('test')->test;
        $result = $collection->updateOne(['unique_id' => 'b4f5393a3a7f822eabd3d6eead66e533'], [
            '$set' => [
                'history.202309' => '$history.202308'
            ],
        ], ['upsert' => true]);
db.test.updateOne(
   {"unique_id": "b4f5393a3a7f822eabd3d6eead66e533"},
   [
      { $set: { "history.202309": "$history.202308" } }
   ],
   {"upsert": true}
);

Hi @hut_lim_chau, it looks like you want to run an update using an aggregation pipeline. This requires you to pass an array of pipeline stages. Your PHP code is missing the surrounding array. To make this a little more obvious, I’ve reformatted the updateOne code:

$result = $collection->updateOne(
    ['unique_id' => 'b4f5393a3a7f822eabd3d6eead66e533'],
    [ '$set' => ['history.202309' => '$history.202308'] ],
    ['upsert' => true]
);

If you compare this to the shell example, you’ll note that the $set operator is not nested in an array. Once you change this, it will work as expected. Note that I’ve also added an object cast to the pipeline stage. While this isn’t necessary, it can help spot such issues in the future.

$result = $collection->updateOne(
    ['unique_id' => 'b4f5393a3a7f822eabd3d6eead66e533'],
    [
        (object) [ '$set' => ['history.202309' => '$history.202308'] ],
    ],
    ['upsert' => true]
);
2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.