Archivo

Archivo para la Categoría "Bases de datos"

Doctrine 2 ORM

3 marzo, 2011 3 comentarios

Doctrine 2 es un ORM (Object-Relational Mapper) para PHP. Un ORM provee un sistema de persistencia para objetos PHP.

Doctrine 2 se sitúa encima de una capa de abstracción de bases de datos (DBAL). La principal tarea del mapeador es traducir de forma trasparente los objetos PHP en filas de una base de datos relacional y viceversa.

Una de las características claves es escribir queries en un dialecto propio similar al SQL, llamado Doctrine Query Language (DQL), inspirado por HQL de Hibernates.

Doctrine 2 es recomendable para aplicaciones que utilizen el paradigma de la programación orientada a objetos. El único requerimiento obligatorio es la versión 5.3.0 de PHP y opcional aunque recomendable la extensión APC.

Doctrine 2 está dividido en tres principales paquetes:

  • Common
  • DBAL (inclue Common)
  • ORM (incluye Common+DBAL)

El paquete Common contiene componentes altamente reutilizables. El namespace raíz es Doctrine\Common.

El paquete DBAL contiene una capa de abstracción de acceso a base de datos situada encima de PDO cuyo objetivo es proporcionar una API que haga de puente entre los diefrentes sistemas gestores de bases de datos. El namespace raíz es Doctrine\DBAL.

El paquete ORM contiene el mapeador objeto-relacional que provee la persistencia de objetos PHP a una base de datos. El namespace raíz es Doctrine\ORM.

Podemos descargar Doctrine2 desde:

http://www.doctrine-project.org/projects/orm/download

Una entrada rapidísima (no tengo mucho tiempo últimamente) para ponernos en contexto de lo que es Doctrine 2. En la siguiente entrada estudiaremos de forma resumida su arquitectura.

Categorías:Bases de datos, Doctrine Etiquetas: , ,

MongoDB: Modificando documentos

17 febrero, 2011 Deja un comentario

Podemos modificar los documentos una vez se han insertados en la base de datos. El método update toma dos parámetros, un objeto que especifica los documentos que hay que modificar y un objeto que especifica que cambios deben de hacerse en los documentos.

Las modificaciones son atómicas, esto quiere decir que si dos modificaciones ocurren al mismo tiempo, se llevará a cabo la primera que el servidor realize, a continuación, se realizará la segunda modificación.

Podemos también modificar el esquema de un documento ya que MongoDB es una base de datos que no utiliza esquema.

Un error común es obtener con el objeto criteria más de un documento y entonces modificarlo con un documento nuevo. Esto provocará que el segundo documento que modifiquemos provoque un error de clave duplicada. La solución consiste en asegurarse de que solo modificamos un solo documento.

Ejemplo: Imaginar que tenemos tres usuarios que se llaman Fran.

usuarios.find()
{"_id" : ObjectId("4b2b9f67a1f631733d917a7b"), "nombre":"Fran", "edad":65},
{"_id" : ObjectId("4b2b9f67a1f631733d917a7c"), "nombre":"Fran", "edad":20},
{"_id" : ObjectId("4b2b9f67a1f631733d917a7d"), "nombre":"Fran", "edad":49}

Ahora queremos aumentar en uno la edad del segundo Fran y realizamos lo siguiente:

> fran = db.usuarios.findOne({"nombre":"Fran", "edad":20})
{
  "_id" : ObjectId("4b2b9f67a1f631733d917a7c"),
  "nombre" : "Fran",
  "edad" : 20
}
> fran.edad++
> db.usuarios.update({"nombre":"Fran"}, fran)
> E11001 duplicate key on update

Obtenemos el usuario Fran cuya edad es 20. Sumamos uno a la edad y modificamos todos los documentos que tengan como nombre Fran con el documento que hemos recuperado y modificado. El primero que intenta modificar es el Fran que tiene 65 años. Intenta insertar el documento Fran de 21 años pero como ya existe un documento con la misma clave _id que es el Fran que tiene 20 años, falla al insertar.

Podemos modificar solo ciertas partes de un documento, añadiendo, modificando o borrando claves, incluso manipulando arrays y documentos embebidos. Para ello utilizamos los modificadores. Cuando utilizamos este tipo de mofidicadores no podemos cambiar el valor de la clave _id.

- Modificador $set y $unset:

El modificador $set cambia el valor de una clave, si la clave no existe la crea. Este modificador puede utilizarse para añadir nuevas claves a los documentos.

Imaginar que tenemos este documento:

{
  "_id" : ObjectId("4b253b067525f35f94b60a31"),
  "titulo" : "Post uno",
  "contenido" : "Contenido del post uno"
}

Podemos añadir una nueva clave:

posts.update({"titulo": "Post uno"}, {"$set":{"autor":"Fran"}})

El documento cambiará a :

{
  "_id" : ObjectId("4b253b067525f35f94b60a31"),
  "titulo" : "Post uno",
  "contenido" : "Contenido del post uno",
  "autor" : "Fran"
}

Podemos utilizar el modificador $unset para borrar una clave:

posts.update({"titulo": "Post uno"}, {"$unset":{"autor": 1}})

Siempre que queramos modificar un documento, añadiendo, cambiando o borrando una clave debemos de utilizar modificadores. Un error común es intentar lo siguiente:

posts.update ({"title": "Post uno"}, {"author": "Fran"})

Esto modificará completamente todos los documentos cuyo titulo sea Post uno con el documento {“author”: “Fran”}, no añadirá la clave author.

- Modificador $inc:

Para incrementar o decrementar un valor numérico podemos utilizar el modificador $inc. No puede utilizarse con otros tipos como string, solamente en tipos numéricos como integers, long o doubles.

Ejemplo: Imaginar que tenemos un sistema de contador de visitas a nuestros post del blog:

<

{
  "_id" : ObjectId("4b253b067525f35f94b60a31"),
  "titulo" : "Post uno",
  "visitas" : 52
}

Cada vez que alguien visite nuestro post debemos de modificar el número de visitas.

posts.update({"title": "Post uno"}, {"$inc": {"visitas": 1}})
- Modificador $push, $ne y $addToSet:

Podemos utilizar el modificador $push para añadir un elemento al final de un array. También podemos añadir un elemento al array siempre que no se encuentre ya dentro, para ello podemos utilizar el modificador $ne. Esto último también podemos conseguirlo utilizando el modificador $addToSet.

Ejemplo:

> db.blog.posts.findOne()
{
  "_id" : ObjectId("4b2d75476cc613d5ee930164"),
  "titulo" : "Titulo uno",
  "contenido" : "Contenido uno"
}
> db.blog.posts.update({"titulo" : "Titulo uno"}, {$push : {"comentarios" :
... {"nombre":"fran", "email":"fran@ejemplo.com", "contenido":"buen post"}}})
> db.blog.posts.findOne()
{
  "_id" : ObjectId("4b2d75476cc613d5ee930164"),
  "titulo" : "Titulo uno",
  "contenido" : "Contenido uno",
  "comentarios" : [
    {
      "nombre" : "fran",
      "email" : "fran@ejmplo.com",
      "contenido" : "buen post"
    }
  ]
}

El modificador $push se traduce en este ejmplo como pon un comentario dentro de comentarios.

Los modifcadores $ne y $addToSet lo utilizamos cuando solo queremos insertarlo si no existe dentro del array:

usuarios.findOne({"_id" : ObjectId("4b2d75476cc613d5ee930164")})
{
  "_id" : ObjectId("4b2d75476cc613d5ee930164"),
  "nombre" : "fran",
  "emails" : [
    "fran@hotmail.com",
    "fran@gmail.com",
    "fran@yahoo.com"
  ]
}

> db.usuarios.update({"_id" : ObjectId("4b2d75476cc613d5ee930164")},
... {"$addToSet" : {"emails" : "fran@gmail.com"}})
> db.usuarios.findOne({"_id" : ObjectId("4b2d75476cc613d5ee930164")})
{
  "_id" : ObjectId("4b2d75476cc613d5ee930164"),
  "nombre" : "fran",
  "emails" : [
    "fran@hotmail.com",
    "fran@gmail.com",
    "fran@yahoo.com"
  ]
}
- Modificadores $pop y $pull:

Para borrar elementos de un array podemos utilizar el modificador $pop. Si lo utilizamos así {$pop : {clave : 1}} borramos el último elemento del array. Si lo utilizamos así {$pop : {clave : -1}} borramos el primer elemento del array.

El modificador $pop se queda corto pero podemos utilizar el modificador $pull para borrar elementos de un array que coincidan con un criterio.

Ejemplo: Imaginar que tenemos una lista de usuarios con sus preferencias de deportes y queremos eleminar un deporte de todas las preferencias:

> db.usuarios.findOne({"_id" : ObjectId("4b2d75476cc613d5ee930164")})
{
  "_id" : ObjectId("4b2d75476cc613d5ee930164"),
  "nombre" : "fran",
  "deportes" : [
    "futbol",
    "voley",
    "basquet"
  ]
}
> db.usuarios.update({}, {"$pull" : {"deportes": "voley"}})
> db.usuarios.findOne({"_id" : ObjectId("4b2d75476cc613d5ee930164")})
{
  "_id" : ObjectId("4b2d75476cc613d5ee930164"),
  "nombre" : "fran",
  "deportes" : [
    "futbol",
    "basquet"
  ]
}
- Modificador posicional:

Existen dos formas de acceder a los elementos de un array, por la posición y utilizando el operador posicional (el caracter $). Todavía no lo hemos dicho pero al igual que sucede en JavaScript, los arrays son de índice cero.

Ejemplo: Imaginar que tenemos un blog con post donde la gente puede comentar:

> db.blog.posts.findOne()
{
  "_id" : ObjectId("4b329a216cc613d5ee930192"),
  "titulo" : "Post uno",
  "comentarios" : [
    {
      "comentario" : "Bueno",
      "autor" : "Fran",
      "votos" : 0
    },
    {
      "comentario" : "Bonito",
      "autor" : "Estef",
      "votos" : 3
    },
    {
      "comentario" : "Barato",
      "autor" : "Jose",
      "votos" : -1
    }
  ]
}

Si queremos incrementar el numero de votos del primer comentario podríamos hacer lo siguiente ya que sabemos que tenemo que modificar los votos del primer comentario del post que queremos.:

> db.blog.update({"post" : ObjectId("4b329a216cc613d5ee930192") },
...{"$inc": {"comentarios.0.votos" : 1}})

Pero en la mayoría de los casos no sabremos cual es el índice del array que queremos modificar a no ser que seleccionemos el documento y lo examinemos. Una alternativa a esto es utilizar el operador posicional. Por ejemplo si queremos cambiar el nombre del comentario que ha realizado estef por el nombre de Alex:

> db.blog.update({"comentarios.autor" : "Estef"},
... {"$set" : {"comentarios.$.autor" : "Alex"}})

El operador posicional solo modifica el primer documento que encuentra.

Categorías:MongoDB

MongoDB: Insertando y borrando documentos.

16 febrero, 2011 Deja un comentario

Ya hemos visto como realizar operaciones CRUD en MongoDB. Vamos a ver con más detalle estas operaciones.

Insertando documentos

Recordamos que para insertar un documento basta con utilizar el método insert:

db.coleccion.insert({"clave":"valor"})

Cuando insertamos un documento el driver que estemos utilizando convierte la estructura de los datos en BSON, lo que se conoce como JSON binario, y lo envía a la base de datos. La base de datos entiende BSON y comprueba que todos los documentos tengan una clave _id y que no exceda los 4MB pero no realiza comprobaciones de tipos válidos. La mayoría de drivers de los lenguajes de programación disponen de un mecanismo para validar tipos de datos antes de ser enviados a la base de datos.

De todas formas podemos iniciar el servidor MongoDB con la opcion -objcheck si queremos que compruebe los tipos de los datos antes de ser insertados teniendo en cuenta que esto disminuye el rendimiento.

MongoDB también permite insercciones por lotes cuando queremos insertar un gran conjunto de documentos.

Además MongoDB no ejecuta código cuando insertamos por lo que no es vulnerable a los tradicionales ataques de inyecciones SQL.

Borrando documentos

Recordamos que para borrar documentos utilizamos el método remove:

db.posts.remove({"autor": "Francisco"})

Esto borra toda la colección posts. A esta función se le puede pasar un objeto criteria que especifica que documentos deben de ser borrados. Por ejemplo si queremos borrar los documentos cuyo autor sea Francisco:

db.posts.remove()

Una vez que los documentos han sido borrados no hay manera de volver a recuperarlos.

Borrar documentos suele ser una operación rápida pero si queremos borrar toda una colección es más rápido utilizar el método drop_collection:

db.drop_collection("posts")

Un ejemplo de benchmark. Si hay insertados un millón de documentos y los borramos todos con remove tarda aproximadamente un mínuto en un MacBook Air, pero utilizando el método drop_collection tarda 0.1 segundos.

Categorías:MongoDB

MongoDB: Primeros pasos

15 febrero, 2011 1 comentario

Seguimos con nuestro proceso de investigación. Vamos a ver como iniciarnos con MongoDB. Esta entrada es un breve resumen del capítulo 2 del libro MongoDB: The Definitive Guide. Primero nos descargamos MongoDB en la versión para nuestro sistema operativo, lo extraemos en un directorio y ejecutamos mongod.exe.

Lo podéis descargar de la página oficial de MongoDB:

http://www.mongodb.org/downloads

Cuando ejecutamos mongod.exe sin argumentos utiliza por defecto el directorio C:\data\db si estamos en Windows y el puerto 27017.

Si el directorio data\db no está creado o no tiene permisos de escritura el servidor MongoDB no arrancará. Así que sino lo tenemos creado lo creamos. El servidor también puede fallar si el puerto 27017 está ocupado.

Si todo ha funcionado correctamente veremos algo de información, como la versión. MongoDB también crea un servidor HTTP muy básico que escucha en el puerto 28017.

Para parar el servidor podemos teclear Ctrl+C en la terminal que hemos utilizado para arrancarlo.

MongoDB Shell

MongoDB incorpora una shell de JavaScript que permite comunicarnos con la instancia de MongoDB a través de la línea de comandos.

Para iniciar la shell ejecutamos mongo.exe y se conectará automáticamente al servidor MongoDB que habíamos iniciado anteriormente.

La shell es un intérprete de JavaScript por lo que podemos escribir scripts que pueden ser interpretados por la propia shell.

> x=200
200
> x/5
40

También podemos utilizar las librerías estándares de JavaScript.

> Math.sin(Math.PI/2)
1
> new Date("2010/1/1");
"Fri Jan 01 2010 00:00:00 GMT-0500 (EST)"
> "Hello, World!".replace("World", "MongoDB");
Hello, MongoDB!

También podemos escribir funciones en varias líneas, la shell detecta automáticamente las sentencias JavaScript cuando tecleamos Enter.

El verdadero poder de la shell JavaScript es que es un cliente MongoDB. Cuando iniciamos la shell, el cliente se conecta a la base de datos de prueba del servidor MongoDB y guarda la conexión en la variable db.

Podemos seleccionar la base de datos con el comando use:

> use foobar
switched to db foobar

Si accedemos al contenido de la variable db nos devolverá un string con el nombre de la base de datos que estamos utilizando:

>db
foobar

Operaciones básicas con el shell

Podemos utilizar las operaciones CRUD, crear, modificar, leer y borrar, para manipular y ver los datos en el shell.

Create:

La función insert añade un documento a la colección. Por ejemplo, si estuvieramos almacenando un post de un blog.

Primero creariamos una variable local llamada post que es un objeto JavaScript que representa nuestro documento. Puede tener unas claves como “title”, “content” y “date”.

> post = {"title" : "My Blog Post",
... "content" : "Here's my blog post.",
... "date" : new Date()}
{
  "title" : "My Blog Post",
  "content" : "Here's my blog post.",
  "date" : "Sat Dec 12 2009 11:23:21 GMT-0500 (EST)"
}

Este objeto es un documento MongoDB válido, así que podemos guardarlo en la colección blog usando el método insert:

> db.blog.insert(post)

El post del blog se ha guardado en la colleción blog. Podemos obtenerlo con el método find:

> db.blog.find()
{
  "_id" : ObjectId("4b23c3ca7525f35f94b60a2d"),
  "title" : "My Blog Post",
  "content" : "Here's my blog post.",
  "date" : "Sat Dec 12 2009 11:23:21 GMT-0500 (EST)"
}

Podemos ver que se ha añadido una clave “_id”.

Read:

El método find devuelve todos los documentos de la colección. Si solo queremos obtener uno podemos utilizar el método findOne:

> db.blog.findOne()
{
  "_id" : ObjectId("4b23c3ca7525f35f94b60a2d"),
  "title" : "My Blog Post",
  "content" : "Here's my blog post.",
  "date" : "Sat Dec 12 2009 11:23:21 GMT-0500 (EST)"
}

Tanto a find como a findOne se les pueden pasar un objeto cuya función es similar al concepto de query en las bases de datos relacionales. Lo veremos más adelante.

Update:

Si queremos modificar el post que hemos insertado anteriormente podemos utilizar la función update. Esta función toma dos parámetros, el primero es un objeto cuya función es encontrar qué documento debe ser modificado, y el segundo es el nuevo documento. Vamos a imaginar que decidimos que se pueda publcar comentarios en el blog. Necesitaremos un array de comentarios como valor para la nueva clave de nuestro documento.

El primer paso es modificar la variable post anterior y añadir una clave “comments”:

> post.comments = []
[ ]

Entonces modificamos el antiguo post con el nuevo:

>db.blog.update({title:"My Blog Post"}, post)

Ahora si buscamos el documento veremos que se ha añadido una nueva clave “comments” con un array vacío de comentarios.

> db.blog.find()
{
  "_id" : ObjectId("4b23c3ca7525f35f94b60a2d"),
  "title" : "My Blog Post",
  "content" : "Here's my blog post.",
  "date" : "Sat Dec 12 2009 11:23:21 GMT-0500 (EST)"
  "comments" : [ ]
}
Delete:

La función remove borra documentos permanentemente de la base de datos. Hay que tener especial cuidado porque si se utiliza sin ningún parámetro borra todos los documentos de la colección. Como find y update, acepta como parámetro un objeto criteria que se utiliza para encontrar los documentos que se quieren borrar.

> db.blog.remove({title : "My Blog Post"})

Ahora la colección está vacía.

Consejos para usar la shell

El comando help nos devuelve una lista con la ayuda de como utilizar algunos comandos:

> help
 
HELP
show dbs show database names
show collections show collections in current database
show users show users in current database
show profile show recent system.profile entries w. time >= 1ms
use <db name> set current database to <db name>
db.help() help on DB methods
db.foo.help() help on collection methods
db.foo.find() list objects in collection foo
db.foo.find( { a : 1 } ) list objects in foo where a == 1
it result of the last line evaluated

Tipos de datos

Vamos a ver los tipos de datos soportados por MongoDB. Los documentos en MongoDB se almacenan con una notación JSON (www.json.org), que son similares a los objetos en JavaScript. JSON es una notación de datos que permite utilizar solamente seis tipos de datos, pero MongoDB amplia los tipos permitiendonos trabajar con algunos más, como por ejemplo, las fechas.

null:

Null puede ser usado para representar un valor nulo o un campo que no existe:

{"x" : null}

boolean:

Booleano que puede tomar los valores true o false:

{"x" : true}

enteros de 32 y 64 bits y números en coma flotante:

{"x" : 150}
{"x" : 3.1416}

string:

Una cadena de caractéres UTF-8:

{"x" : "Hola"}

símbolo (symbol):

Aún no sé muy bien para que sirven, pero la shell no los soporta.

object id:

Un id único para cada documento.

{"x" : ObjectId()}

fecha (date):

Para almacenar fechas. La zona horaria no se almacena.

{"x" : new Date()}

expresiones regulares:

Los documentos pueden contener expresiones regulares.

{"x" : /Hola/i}

código (code):

Los documentos pueden contener código JavaScript.

{"x" : function() { /* ... */ }}

datos binarios:

Los datos bianros son una cadena arbitraria de bytes.

undefined

También podemos utilizar undefinided en los documentos.

{"x" : undefined}

array:

Una lista con un conjunto de valores:

{"x" : ["a", "b", "c"]}

documentos embebidos:

Los documentos pueden contener otros documentos:

{"x" : {"foo" : "bar"}}

Ya sabemos como seleccionar una base de datos, y comenzar a realizar operaciones CRUD a través de la shell. No hace falta crear ninguna base de datos, ni colecciones, tal como lo hacen las bases de datos relacionales como MySQL, debido a que MongoDB crea todo la primera vez que se inserta un documento.

Categorías:MongoDB

Introducción a MongoDB: Conceptos básicos teóricos.

14 febrero, 2011 1 comentario

Al igual que con Symfony2, para el mismo proyecto he decidido investigar y experimentar un poco con MongoDB, más que nada para ver que es eso de noSQL que se oye tanto hoy en día.

He sacado un libro de la biblioteca, en concreto, MongoDB The definitive Guide de O’Reilly y me lo estoy leyendo. Está en perfecto inglés, así que iré comentando por aquí un resumen breve de cada uno de los capítulos del libro.

¿Qué es MongoDB?

MongoDB es una base de datos documental, no una base de datos relacional. Es una de las bases de datos que han surgido del movimiento noSQL y que intenta incrementar la escalabilidad del sistema. La idea básica es sustituir el concepto de fila por el concepto de documento.

Vamos a introducir los conceptos teóricos de MongoDB:

- Un documento (document) es la unidad básica de datos en MongoDB, normalmente equivale al concepto de fila en una base de datos relacional.

- Una colección (collection) puedes ser considerada como una tabla en una base de datos relacional.

- Una sola instancia de MongoDB puede alojar múltiples bases de datos independientes, que pueden tener sus propias colecciones y permisos.

- MongoDB incluye una shell de JavaScript que es útil para temas de administración y manipulación de datos.

Documentos:

Un documento es un conjunto de claves con valores asociados. La representación de un documento difiere del lenguaje de programación utilizado, puede ser un mapa, una tabla hash o un dictionario. En JavaScript por ejemplo los documentos se representan como objetos:

{"greeting" : "Hello, world!"}

Este es un ejemplo sencillo de documento y contiene una sola clave greeting con un valor Hello, world!. La mayoría de documentos son más complejos y contienen múltiples pares de clave/valor.

{"greeting" : "Hello, world!", "foo" : 3}

A destacar:

- Las claves de un documento son strings.

- No debería utilizarse el carácter . y $, punto y dólar.

- No debería comenzar con _, barrabaja.

- Las claves son case-sensitive, sensibles a mayúsculas y minúsculas, por lo que no es lo mismo:

{"foo" : 3}
{"Foo" : 3}

- Cada documento, tiene una clave (key), _id, que es única en toda la colección.

- Y lo más importante, un documento MongoDB no puede contener claves duplicadas:

{"greeting" : "Hello, world!", "greeting" : "Hello, MongoDB!"}
Colecciones:

Una colección es un conjunto de documentos. Podemos verlo como si fuera una tabla en una base de datos relacional.

A destacar:

- Una colección se identifica por su nombre.

- El string vacío “” no es un nombre válido de colección.

- El nombre de la colección no puede contener el carácter , es decir, el caractér null y tampoco debería contener el carácter $, dólar.

- No deberías crear colecciones que empiezen con system. ya que es un prefijo reservado para las colecciones del sistema. Por ejemplo system.users es una coleccion que contiene los usuarios de las bases de datos.

Esquema libre (Schema-Free):

Esquema libre significa que los documentos de una misma colección pueden tener estructuras diferentes. Por ejemplo, estos dos documentos pueden formar parte de la misma colección:

{"greeting" : "Hello, world!"}
{"foo" : 5}

Como vemos, podemos guardar dentro de una colección cualquier tipo de documentos, pero no es una buena idea utilizar una única colección para almacenar todo. Algunos motivos:

- Mantener diferentes tipos de documentos en una misma colección puede ser una pesadilla.

- Es mucho más rápido obtener una lista de documentos que tengan la misma estructura.

- Es una buena práctica imponer una cierta estructura, sobretodo cuando queremos crear índices.

Subcolecciones:

Podemos organizar colecciones en subcolecciones utilizando namespaces separados por el . carácter. Por ejemplo si tenemos un blog podemos tener una colección blog.posts y otra colección blog.autores.

Las subcolecciones son una gran manera de organizar los datos en MongoDB.

Bases de datos:

Se pueden agrupar las colecciones en bases de datos, al igual que en una base de datos relacional agrupamos tablas.

Una sola instancia de MongoDB puede albergar varias bases de datos, cada una con sus propios permisos y archivos separados. Una buena idea es separar los datos de cada aplicación en una misma base de datos.

Separar las bases de datos son útiles para almacenar datos de varias aplicaciones del mismo usuario o del mismo servidor de MongoDB.

Como las colecciones, los nombres de las bases de datos también tienen restricciones:

- No puede ser el string vacío “, ni puede contener estos carácteres: ‘ ‘ (espacio en blanco),. (punto),$ (dolar), /,\ o .

- Los nombres deben estar en minúsculas.

- Nombres limitados a un máximo de 64 bytes.

Categorías:MongoDB
Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 123 seguidores