Question

Utilisation du pilote pymongo nu pour python connecter à MongoDB, pourquoi est-ce que l'utilisation d'une instance ObjectId comme la clé d'un document incorporé déclenche une erreur de InvalidDocument?

Je suis en train de documents de lien en utilisant ObjectID et cant semblent comprendre pourquoi je voudrais les convertir en chaînes lorsque celles créées automatiquement pour le pilote sont des instances de ObjectId.

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')

Dans la pratique, les ids liés représentent les documents qui contiennent des questions, et les valeurs dans le dictionnaire ici calée comme « autreschoses » par exemple représenterait les réponses de ce document individuel à cette question particulière.

Y at-il une raison application ObjectID comme celui-ci ne sera pas encode en BSON et échoue alors? Est-il impossible d'imbriquer ObjectIds dans les documents comme celui-ci à des références croisées? Ai-je mal compris le but de les?

Était-ce utile?

La solution

La spécification BSON dicte que les clés doivent être des chaînes, donc PyMongo a raison de rejeter cela comme un document non valide (et serait peu importe à quel niveau un ObjectId a été utilisé comme une clé, que ce soit au niveau supérieur ou dans un document incorporé). Cela est nécessaire, entre autres, de sorte que le langage de requête peut être sans ambiguïté. Imaginez que vous aviez ce document (et qu'il était un document BSON valide):

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

Et puis vous avez essayé de requête avec:

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

Si cela devait retourner ce document? Si cette chaîne est auto-emballé dans un ObjectId? Comment savoir quand Mongo qui peut être boxed automatiquement, et comment désambiguïser dans des cas comme ce document?

Une solution alternative possible à votre problème est d'avoir un tableau de documents intégrés comme:

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

Ceci est BSON valide et sera également indexables plus efficacement. Si vous ajoutez un index sur answers, vous pouvez rechercher efficacement des correspondances exactes sur ces sous-documents; si vous ajoutez un index sur answers.answer_id, vous pouvez effectuer une recherche efficace par le ObjectId de la réponse que vous cherchez (et ainsi de suite).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top