2010-12-13 15 views
11

es posible obtener el nuevo _id/modificada después de la consulta? ejemplo de código:obtener mongodb objeto _id después upsert con php

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

$ clave no está sosteniendo el objeto nuevo/viejo _id y supongo que no lo hará $ datos, ya sea porque es sólo una instrucción.

Respuesta

16

Sí - es posible utilizar una sola consulta.

MongoDB incluye un comando findAndModify que puede modificar atómicamente un documento y devolverlo (de forma predeterminada, realmente devuelve el documento antes de que se haya modificado).

Los controladores de PHP no incluyen un método conveniente para esto en la clase de colección (sin embargo, consulte this bug), pero aún se puede usar (tenga en cuenta que mi PHP es terrible, por lo que puedo haber hecho un error de sintaxis en el siguiente fragmento):

$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

Ahh - la 'findAndModify' que tan rara vez lo utilizan siempre olvido que existe :) - Es bueno que se pruebe que está mal ocasionalmente;) – gnarf

+0

@gnarf: No se preocupe.Lo que me parece extraño es que no hay una forma de obtener el _id automáticamente en PHP. Estoy acostumbrado a los controladores de Python que devuelven el _id en cada [upsert] (http://api.mongodb.org/ python/1.9% 2B/api/pymongo/collection.html # pymongo.collection.Collection.save) – Cameron

15

por si alguien se tropieza con esta pregunta como lo hice, Mongo realmente modificar la matriz de entrada cuando se llama MongoCollection-> save(); - Añadiendo la identificación al final. Por lo tanto, si se llama:

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

Usted tendrá la Identificación del mongo para ese objeto.

+3

Sé que esto también funciona en la función 'insert()'. – Failpunk

+1

Fantástico. No veo ninguna razón para utilizar el complejo 'findAndModify' en lugar de un' save' tradicional si se trata de un estándar, sin adornos, 'upsert'. – Nucleon

+0

Aha! Me preguntaba por qué no había una manera de obtener el '_id' para un upsert en PHP ... Esta debería ser la respuesta aceptada. – Cameron

1

También puede establecer fsync en true en una actualización/upsert, para obtener _ID regresaron al objeto que se ha transmitido a la actualización.

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

Parece que no funciona. – Oleg

3

Me encontré con este problema y lo solucioné preguntando el _id después de la inserción. Pensé en agregar algunos de mis hallazgos en caso de que sean útiles para cualquiera que venga aquí buscando información.

Cuando los resultados upsert en un nuevo documento que se crean en la colección, el objeto devuelto contiene _ID (aquí hay un print_r de un ejemplo):

Array 

(

[updatedExisting] => 0 

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

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

Puede obtener _ID de esto:

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

Sin embargo, si la inserción daba como resultado la actualización de un documento existente, entonces el objeto devuelto no contiene _id.

1

dar a este un tiro:

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

lo que permite decir la $id dado es nulo, se crea un nuevo MongoId, de lo contrario, simplemente convierte la $id existente a un objeto MongoId.

Espero que esto ayude: D

1

El método de actualización devuelve una matriz con el ID del documento UPSERTED:

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