Pregunta

Usando el controlador de Pymongo desnudo para conectar Python a MongoDB, ¿por qué usar una instancia de ObjectId como clave para un documento incrustado plantea un error de Documento Invalid?

Estoy tratando de vincular documentos usando objetos y no puedo entender por qué me gustaría convertirlos en cadenas cuando los creados automáticamente para el controlador son ObjectId instancias.

item = collection.find({'x':'foo'})
item['otherstuff'] = {pymongo.objectid.ObjectId() : 'data about this link'}
collection.update({'x':'foo'}, item)
bson.errors.InvalidDocument: documents must have only string keys, key was ObjectId('4f0b5d4e764df61c67000000')

En la práctica, las ID vinculadas representan documentos que contienen preguntas, y los valores en el diccionario aquí clave como 'Otherstuff', por ejemplo, representarían las respuestas de este documento individual a esa pregunta particular.

¿Hay alguna razón por la que la aplicación de objetos como este no se codificará en BSON y luego falla? ¿Es imposible anidar objetos dentro de documentos como este para una referencia cruzada? ¿He entendido mal el propósito de ellos?

¿Fue útil?

Solución

los Especificación de BSON Dicta que las claves deben ser cadenas, por lo que Pymongo tiene razón al rechazar esto como un documento inválido (y sería independientemente de qué nivel se usara un objeto como clave, ya sea en el nivel superior o en un documento incrustado). Esto es necesario, entre otras razones, para que el lenguaje de consulta pueda ser inequívoco. Imagine que tenía este documento (y que era un documento BSON válido):

{ _id: ...,
  "4f0cbe6d7f40d36b24a5c4d7":           true,
  ObjectId("4f0cbe6d7f40d36b24a5c4d7"): false
}

Y luego intentaste consultar con:

db.foo.find({"4f0cbe6d7f40d36b24a5c4d7": false})

¿Debería esto devolver este documento? ¿Debería esa cadena estar automáticamente en un objeto? ¿Cómo sabría Mongo cuándo puede ser automático y cómo desambiguar en casos como este documento?

Una posible solución alternativa a su problema es tener una variedad de documentos integrados como:

{ answers: [
    { answer_id: ObjectId("..."), summary: "Good answer to this question" },
    { answer_id: ObjectId("..."), summary: "Bad answer to this question" }
  ]
}

Esto es BSON válido y también será indexable de manera más eficiente. Si agrega un índice en answers, puede buscar eficientemente las coincidencias exactas en estos subdocumentos; Si agrega un índice en answers.answer_id, entonces puede buscar eficientemente por el objeto de la respuesta que está buscando (y así sucesivamente).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top