Search code examples
mongodbsymfonydoctrine-ormquery-builderodm

update a field with the value of other field


How can I update a field with the value of other field? For example, I want to update the field updated_at with the value of the field created_at (it's like cloning fields)

$dm->createQueryBuilder('MyBundle:MyService')
            ->update()
            ->multiple(true)
            ->field('updated_at')->set(CREATED_AT_ATRIBUTE)
            ->getQuery()
            ->execute();

Thanks


Solution

  • Option #1: Application side update

    The easiest approach when using Doctrine ODM is to perform the update on the application side. So you fetch all the objects you want to update, make the necessary adjustments and flush them.

    $services = $dm->createQueryBuilder('MyBundle:MyService')
        ->getQuery()
        ->execute();
    
    foreach ($services as $service) {
        $service->setUpdatedAt($service->getCreatedAt());
    }
    
    $db->flush();
    

    $services represents the mongo cursor, which will fetch the documents as you iterate. You can set eagerCursor to true if you want to fetch all the documents from the collection at once.

    Option #2: Database side update

    You can also perform the update directly on the database itself. To do so however, you'll need to create the query yourself as the query builder doesn't support this functionality.

    // Get MongoDB instance from DocumentManager
    $mongo = $dm->getDocumentDatabase('Fully/Qualified/Class/Name')
        ->getMongoDB();
    
    // Iterate over the collection and update each document
    $mongo->execute('
        db.MyServiceCollection.find().forEach(function (item) {
            db.MyServiceCollection.update(
                {_id: item._id},
                {$set: {updated_at: item.created_at}}
            );
        });
    ');
    

    The function used in forEach is just a regular javascript function, so you can insert some more logic in there if you need more control over what you update.