Tipos
MongoDB permite a los programadores guardar y consultar datos expresados tanto en los
tipos básicos de PHP, los tipos compuestos (arrays, arrays asociativos, y objetos), y
en media docena de clases que proporciona el driver MongoDB de PHP (para expresiones
regulares, fechas, y otras aplicaciones especializadas).
Booleanos y &null;
&true;, &false;, y &null; pueden usarse tal cual.
Números
En MongoDB los números son distintos de los strings: "123" no es lo mismo que 123.
Por tanto, si se desea asegurar de que los números se ordenan y comparan correctamente,
debe asegurarse de que realmente se almacenan como números.
123, "b" => "123");
$collection->insert($doc);
$doc->find(array("a" => 123)); // coincide
$doc->find(array("a" => "123")); // no coincide
$doc->find(array("a" => 123.0)); // coincide
$doc->find(array("b" => 123)); // no coincide
$doc->find(array("b" => "123")); // coincide
?>
]]>
Como vemos, los números en coma flotante se comparan y coinciden con los números enteros
tal como cabría esperar.
Números Largos
Por omisión, en sistemas de 32 bits, los números se envían a la base de datos como
enteros de 32 bit. En sistemas 64 bits, se envían como enteros de 64 bit. Para guardar la
compatibilidad, todos los sistemas deserializan los enteros de 64 bit como números
en coma flotante. Los números en coma flotante no son exactos. Si fuera necesario usar
valores exactos, habría que hacerlo ajsutando el
fichero php.ini.
En sistemas de 32 bits, si mongo.long_as_object está habilitado,
los enteros de 64 bit se devolverán como objetos MongoInt64.
El entero se almacenará en el campo value
con una precisión perfecta (como un string).
MongoInt64 puede usarse también para guardar enteros de 64 bit en máquinas
de 32 bits.
En sistemas de 64 bits, puede o bien habilitarse mongo.long_as_object
o mongo.native_long.
mongo.native_long devolverá enteros de 64 bit y
enteros "normales" de PHP. MongoInt32 puede usarse para
almacenar enteros de 32 bit en máquinas de 64 bits.
Debe establecerse un valor en mongo.long_as_object y en
mongo.native_long de acuerdo al comportamiento que se espere, incluso
en el caso de que coincida con los valores por omisión (para prevenir futuros cambios de estos
valores).
Vea también: Opciones de php.ini,
MongoInt32, MongoInt64.
Strings
Los strings deben ser UTF-8. Si no, o bien se convierten a UTF-8
antes de enviarse a la base de datos, o bien se almacenan como datos binarios.
Pueden usarse expresiones regulares para consultar strings, y se expresan usando la clase
MongoRegex.
Datos Binarios
Tanto los textos que no son UTF-8, como las imágenes, o cualuier otro dato binario, debe enviarse
a la base de datos usando el tipo MongoBinData.
Fechas
Pueden crearse fechas usando la clase MongoDate. Se almacenan
como milisegundos a partir de la fecha de referencia.
MongoTimestamp no es para almacenar fechas ni timestamps,
sino que se usa internamente por MongoDB. A no ser que se esté creando una herramienta que
interactúe con los entresijos de réplicas o sharding, se deberá usar
MongoDate, y noMongoTimestamp.
Ids Únicos
El driver creará automáticamente un campo _id antes de
insertar un documento (a no ser que el usuario haya especificado uno). Este campo es una instancia
de MongoId (en otros lenguajes habitualmente se le llama
"ObjectId").
Estos ids se componen de 12 bytes:
4 bytes de timestamp
Dos registros no pueden tener el mismo id si se han insertado en momentos
diferentes.
3 bytes de id de máquina
Dos registros no pueden tener el mismo id si se han insertado en máquinas
diferentes.
2 bytes de id de hebra
Dos registros no pueden tener el mismo id si se han insertado por diferentes
hebras en la misma máquina.
3 bytes de valor incremental
Cada vez que se crea un id, un contador global se incrementa, y se usa
para el incremento del siguiente id.
Por tanto, dos registros no pueden tener el mismo id, a no ser que un único proceso
en una misma máquina trate de insertar 256^3 (más de 16 millones) de documentos en
un segundo, desbordando el campo de incremento.
JavaScript
MongoDB incorpora un motor JavaScript, de modo que se pueden incluir código JavaScript
en las consultas (usando la claúsula $where), enviarlo directamente a la base de datos para
ejecutarlo, y usarlo para llevar a cabo agregaciones.
Por seguridad, en MongoCode utilice el campo scope
cuando vaya a usar variables PHP en JavaScript. Cuando el código no requiera de
valores externos, se puede o bien usar MongoCode o símplemente
un string. Revise la
sección de seguridad para más
información sobre cómo enviar código JavaScript a la base de datos.
Arrays y Objetos
También pueden guardarse arrays y objetos en la base de datos. Los arrays con clave
numérica incremental se almacenarán como arrays. En cualquier otro caso, se almacenarán
como objetos.
insert(array("puntuaciones" => $puntuaciones));
// $puntuaciones se almacenará como un objeto
$puntuaciones = array("pregunta1" => 98, "examen" => 100, "pregunta2" => 73, "final" => 85);
$collection->insert(array("puntuaciones" => $puntuaciones));
?>
]]>
Si consultamos estos objetos en la consola de la base de dato, obtendremos algo similar a esto:
db.students.find()
{ "_id" : ObjectId("4b06beada9ad6390dab17c43"), "puntuaciones" : [ 98, 100, 73, 85 ] }
{ "_id" : ObjectId("4b06bebea9ad6390dab17c44"), "puntuaciones" : { "pregunta1" : 98, "examen" : 100, "pregunta2" : 73, "final" : 85 } }
]]>
La base de datos puede almacenar también objetos PHP arbitrarios (pese a que
se devolverán como arrays asociativos). Los campos se usan para pares clave/valor.
Por ejemplo, la entrada de un blog podría ser así:
autor = $autor;
$this->contenido = $contenido;
$this->fecha = new MongoDate();
}
public function establecerTitulo($titulo) {
$this->titulo = $titulo;
}
}
// crear una entrada de blog sencilla e insertarla en base de datos
$entrada1 = new Entrada("Adam", "Esto es una entrada de un blog");
$blog->insert($entrada1);
// no hay niguna restricción del tipo usado en el campo "autor", de manera que podemos
// usarlo como un objeto anidado
$autor = array("nombre" => "Fred", "karma" => 42);
$entrada2 = new Entrada($autor, "Ésta es otra entrada de blog.");
// creamos un campo más para el título
$entrada2->establecerTitulo("Segunda Entrada");
$blog->insert($entrada2);
?>
]]>
En la consola de la base de datos, lo veríamos parecido a esto:
db.blog.find()
{ "_id" : ObjectId("4b06c263edb87a281e09dad8"), "autor" : "Adam", "contenido" : "Esto es una entrada de un blog", "comentarios" : [ ], "fecha" : "Fri Nov 20 2009 11:22:59 GMT-0500 (EST)" }
{ "_id" : ObjectId("4b06c282edb87a281e09dad9"), "autor" : { "nombre" : "Fred", "karma" : 42 }, "contenido" : "Ésta es otra entrada de blog", "comentarios" : [ ], "fecha" : "Fri Nov 20 2009 11:23:30 GMT-0500 (EST)", "titulo" : "Segunda Entrada" }
]]>
El driver no detecta referencias cíclicas en arrays ni en objetos. Por
ejemplo, esto emitiría un error fatal:
insert($GLOBALS);
?>
]]>
Si se necesitara insertar documentos que pudieran tener dependencias cíclicas, deberá
comprobarse a mano antes de pasarlo al driver.
&reference.mongo.mongoid;
&reference.mongo.mongocode;
&reference.mongo.mongodate;
&reference.mongo.mongoregex;
&reference.mongo.mongobindata;
&reference.mongo.mongoint32;
&reference.mongo.mongoint64;
&reference.mongo.mongodbref;
&reference.mongo.mongominkey;
&reference.mongo.mongomaxkey;
&reference.mongo.mongotimestamp;