2012-01-24 10 views
5

En este post MongoDB finding nested elements, autor afirma que la estructura del documento mongodb es

 car : { "$ref" : "cars" , "$id" : { "$oid" : "4e8478ace4b0dea06288ad63"}} 

cuando traté de reproducir el problema, me encontré con algunos comportamientos extraños con la inserción mongodb

Cuando se ejecuta la inserción en los datos de ejemplo anterior, obtuve siguiente error

> db.sample.insert({car:{ "$ref" : "cars" , "$id" : { "$oid" : "4e8478ace4b0dea06288ad63"}}}) 
Tue Jan 24 14:09:07 uncaught exception: field names cannot start with $ [$oid] 

se dice que los nombres de campo no pueden comenzar con $.

Si ése es el caso, para que no funcione si quito $ a partir del Viejo y dejó el resto sin tocar $ref & $id

> db.sample.insert({car:{ "$ref" : "cars" , "$id" : { "oid" : "4e8478ace4b0dea06288ad63"}}}) 
    > db.sample.find() 
{ "_id" : ObjectId("4f1e6fbc403aae757ec6dea5"), "car" : { "$ref" : "cars", "$id" : { "oid" : "4e8478ace4b0dea06288ad63" } } } 

sorprendentemente funcionó. Ahora acepta los campos comienzan con $

También cuando he intentado esta consulta

> db.sample.insert({ "$ref" : "cars" }) 
document to insert can't have $ fields 

tengo el error de vuelta.

No entiendo qué causa esto? alguien tiene una idea clara?

Respuesta

4

$id y $ref son identificadores especiales utilizados para dbrefs. De lo contrario, los nombres de campo que comienzan con $ no están permitidos.

Sin embargo, su documento de primer nivel no debe ser un dbref en sí mismo, de ahí el error "el documento para insertar no puede tener $ fields".

Sin embargo, los dbrefs están permitidos como subdocumentos, p. (Desde el official docs)

"name" : "Joe", 
"classes" : [ 
     { 
       "$ref" : "courses", 
       "$id" : ObjectId("4b0552b0f0da7d1eb6f126a1") 
     } 
] 

Ahora $oid no es un identificador especial, y no está permitido porque el $ tiene una semántica especial: Piense en $inc. Eso es un operador, pero si se permitieran los nombres de campo $, también podría ser el nombre de un campo.

usted tiene que ser cuidadoso cuando se utiliza el positional operator in updates:

El operador posicional no se puede combinar con un upsert ya que requiere un elemento de la matriz a juego. Si su actualización da como resultado una inserción, el "$" se usará literalmente como el nombre del campo.

+1

Sí, esa es la razón ...gracias – RameshVel

+0

¿hay alguna manera de arriesgar el DBRefs? – Backlit

+0

@Backlit: Lo siento, no entiendo la pregunta. ¿Desea cambiar la sintaxis de los dbrefs? Asegúrese de comprender que no tiene que usar dbrefs; de hecho, generalmente no es necesario y los documentos oficiales recomiendan que use enlaces directos simples, como 'UserId: 423434'. – mnemosyn

1

$ref$id y $db son las únicas claves válidas que comienzan con un signo de dólar - que están relacionados con la convención DBRef.

La razón por la que no puede usar sus propias llaves comenzando con un signo de dólar es porque tiene Specialmeaning y de lo contrario crearía ambigüedad.

+0

¿Hay alguna forma de evitar esto? Por ejemplo, escapar de ellos? – devo