Получить mongodb _id объект после upsert с php

можно ли получить новый/обновленный _id после запроса? пример кода:

$key = array( 'something' => 'unique' );
$data = array( '$inc' => array( 'someint' => 1 ) );
$mongodb->db->collection->update( $key, $data, array( 'upsert' => true ) );

$key не содержит новый/старый _id-объект, и я предполагаю, что $data не будет либо потому, что это просто инструкция.

Ответ 1

Да - возможно использование одного запроса.

MongoDB включает в себя команду findAndModify, которая может аморфно изменять документ и возвращать его (по умолчанию он фактически возвращает документ до его изменения).

Драйверы PHP не включают удобный метод для этого в классе коллекции (еще - проверьте эту ошибку), но он все равно может использоваться ( обратите внимание, что мой PHP ужасен, поэтому я вполне мог бы сделать синтаксическую ошибку в следующем фрагменте):

$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'];

Ответ 2

На всякий случай кто-то наткнется на этот вопрос, как я, Mongo на самом деле изменит входной массив при вызове MongoCollection- > save(); - добавление идентификатора в конец. Итак, если вы вызываете:

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

У вас будет идентификатор mongo для этого объекта.

Ответ 3

Я столкнулся с этой проблемой и работал вокруг нее, обратившись назад к _id после upsert. Я думал, что добавлю некоторые мои выводы, если они будут полезны всем, кто приходит сюда, ища информацию.

Когда upsert приводит к созданию нового документа в коллекции, возвращаемый объект содержит _id (здесь print_r примера):

Array

(

[updatedExisting] => 0

[upserted] => MongoId Object
    (
        [$id] => 506dc50614c11c6ebdbc39bc
    )

[n] => 1
[connectionId] => 275
[fsyncFiles] => 7
[err] => 
[ok] => 1
)

Вы можете получить _id из этого:

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

Однако, если upsert привел к обновлению существующего документа, то возвращаемый объект не содержит _id.

Ответ 4

Вы также можете установить fsync в true в update/upsert, чтобы вернуть _id объекту, который был передан в обновление.

$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.

Ответ 5

Сделайте снимок:

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));
}

Итак, пусть переданный $id имеет значение null, создается новый MongoId, иначе он просто преобразует существующий $id в объект MongoId.

Надеюсь, это поможет: D

Ответ 6

Метод обновления возвращает массив с идентификатором документа UPSERTED:

Array
(
    [ok] => 1
    [nModified] => 0
    [n] => 1
    [err] => 
    [errmsg] => 
    [upserted] => MongoId Object
        (
            [$id] => 5511da18c8318aa1701881dd
        )
    [updatedExisting] => 
)