get mongodb _id object after upsert with php

后端 未结 6 1040
我寻月下人不归
我寻月下人不归 2020-12-14 11:56

is it possible to get the new/updated _id after the query? example code:

$key = array( \'something\' => \'unique\' );
$data = array( \'$inc\' => array(         


        
相关标签:
6条回答
  • 2020-12-14 12:08

    Just in case someone stumbles across this question like I did, Mongo will actually modify the input array when you call MongoCollection->save(); - appending the id to the end. So, if you call:

    $test = array('test'=>'testing');
    mongocollection->save($test);
    echo $test['_id'];
    

    You will have the mongo id for that object.

    0 讨论(0)
  • 2020-12-14 12:12

    Yes -- It is possible using a single query.

    MongoDB includes a findAndModify command that can atomically modify a document and return it (by default it actually returns the document before it's been modified).

    The PHP drivers don't include a convenient method for this on the collection class (yet -- check out this bug), but it can still be used (note that my PHP is terrible, so I may very well have made a syntax error in the following snippet):

    $key = array( 'something' => 'unique' );
    $data = array( '$inc' => array( 'someint' => 1 ) );
    $result = $mongodb->db->command( array(
        'findAndModify' => 'collection',
        'query' => $key,
        'update' => $data,
        'new' => true,        # To get back the document after the upsert
        'upsert' => true,
        'fields' => array( '_id' => 1 )   # Only return _id field
    ) );
    $id = $result['value']['_id'];
    
    0 讨论(0)
  • 2020-12-14 12:16

    Give this a shot :

    function save($data, $id = null) {
        $mongo_id = new MongoId($id);
        $criteria = array('_id' => $mongo_id);
        // Wrap a '$set' around the passed data array for convenience
        $update = array('$set' => $data);
        $collection->update($criteria, $update, array('upsert' => true));
    }
    

    So lets say the passed $id is null, a fresh MongoId is created, otherwise it just converts the existing $id to a MongoId object.

    Hope this helps :D

    0 讨论(0)
  • 2020-12-14 12:17

    You can also set fsync to true in an update/upsert, to get the _id returned to the object that has been passed to the update.

    $save = array ('test' => 'work');
    $m->$collection->update(criteria, $save, array('fsync' => true, 'upsert' => true));
    echo $save['_id']; //should have your _id of the obj just updated.
    
    0 讨论(0)
  • 2020-12-14 12:18

    The update method returns an array with the ID of the document UPSERTED:

    Array
    (
        [ok] => 1
        [nModified] => 0
        [n] => 1
        [err] => 
        [errmsg] => 
        [upserted] => MongoId Object
            (
                [$id] => 5511da18c8318aa1701881dd
            )
        [updatedExisting] => 
    )
    
    0 讨论(0)
  • 2020-12-14 12:21

    I ran into this issue and worked around it by querying back the _id after the upsert. I thought I'd add some of my findings in case they're useful to anyone who comes here searching for info.

    When the upsert results in a new document being created in the collection, the returned object contains the _id (here's a print_r of an example):

    Array
    
    (
    
    [updatedExisting] => 0
    
    [upserted] => MongoId Object
        (
            [$id] => 506dc50614c11c6ebdbc39bc
        )
    
    [n] => 1
    [connectionId] => 275
    [fsyncFiles] => 7
    [err] => 
    [ok] => 1
    )
    

    You can get the _id from this:

    $id = (string)$obj['upserted'];
    

    However, if the upsert resulted in an existing document being updated then the returned object does not contain _id.

    0 讨论(0)
提交回复
热议问题