skip to Main Content

In my MongoDB collection, all documents contain a mileage field which currently is a string. Using PHP, I’d like to add a second field which contains the same content, but as an integer value. Questions like How to change the type of a field? contain custom MongoDB code which I don’t want to run using PHP, and questions like mongodb php Strings to float values retrieve all documents and loop over them.

Is there any way to use MongoDBOperationUpdateMany for this, as this would put all the work to the database level? I’ve already tried this for static values (like: add the same string to all documents), but struggle with getting the data to be inserted from the collection itself.

Some further hints:

  • I’m looking for a pure PHP solution that does not rely on any binary to be called using exec. This should avoid installing more packages than needed on the PHP server
  • Currently, I have to use MongoDB in v4.0. Yes, that’s not the most recent version, but I’m not in the position to perform an upgrade

2

Answers


  1. You could use $set like this in 4.2 which supports aggregation pipeline in update.

    $set stage creates a mileageasint based on the previous with $toInt value

    db.collection.updateMany(
       <query>,
       [{ $set: { "mileageasint":{"$toInt":"$mileage" }}}],
       ...
    )
    

    Php Solution ( Using example from here)

    $updateResult = $collection->updateMany(
        [],
        [['$set' => [ 'mileageasint' =>  [ '$toInt' => '$mileage']]]]
    );
    
    Login or Signup to reply.
  2. Try this, please:

    01) MongoDB Aggregate reference:

    db.collectionName.aggregate(
        [
            { "$addFields": { 
                "intField": { "$toInt": "$stringFieldName" } 
            }},
            { "$out": "collectionName" }
        ]
    )
    

    02) Possible PHP solution (Using as reference https://www.php.net/manual/en/mongocollection.aggregate.php):

    $pipeline = array(
        array(
            '$addFields' => array(
                'integerField' => array('$toInt' => '$mileage')
            )
        ),
        array(
            '$out' => 'collection'        
        ),
    );
    $updateResult = $collection->aggregate(pipeline);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search