получить объект 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 не будет, потому что это просто инструкция.
6 ответов
Yes -- можно использовать один запрос.
в MongoDB включает в себя findAndModify
команда, которая может атомарно изменить документ и вернуть его (по умолчанию он фактически возвращает документ до его изменения).
драйверы PHP не включают удобный метод для этого в классе коллекции (пока -- check out эта ошибка), но его все еще можно использовать (обратите внимание, что мой 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'];
на всякий случай, если кто-то наткнется на этот вопрос, как и я, Mongo фактически изменит входной массив при вызове MongoCollection - >save (); - добавление идентификатора до конца. Итак, если вы позвоните:
$test = array('test'=>'testing');
mongocollection->save($test);
echo $test['_id'];
у вас будет идентификатор mongo для этого объекта.
я столкнулся с этой проблемой и обошел ее, запросив _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.
дайте это выстрел:
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
метод update возвращает массив с идентификатором документа UPSERTED:
Array
(
[ok] => 1
[nModified] => 0
[n] => 1
[err] =>
[errmsg] =>
[upserted] => MongoId Object
(
[$id] => 5511da18c8318aa1701881dd
)
[updatedExisting] =>
)
вы также можете установить 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.