Domanda

Uso del driver pymongo nudo di pitone di connessione per MongoDB, perché è che utilizzando un'istanza ObjectId come la chiave per un documento incorporato genera un errore InvalidDocument?

Sto cercando di documenti collegamento mediante objectIds e cant sembrano capire perché vorrei convertirli in stringhe quando quelli creati automaticamente per il conducente sono casi 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')

In pratica gli ID collegate rappresentano i documenti che contengono le domande ei valori nel dizionario qui digitato come 'otherstuff' ad esempio rappresenterebbe risposte di questo documento individuale a quella particolare domanda.

C'è un motivo per applicare objectIds come questo non sarà codificare in BSON e poi fallisce? E 'impossibile objectIds nido all'interno dei documenti come questo a riferimento incrociato? Ho frainteso lo scopo di loro?

È stato utile?

Soluzione

Il BSON spec dettami che le chiavi devono essere stringhe, quindi PyMongo è diritto di rifiutare questo come un documento non valido (e sarebbe indipendentemente da quale livello di ObjectId è stato utilizzato come una chiave, sia a livello superiore o in un documento incorporato). Ciò è necessario, tra l'altro, in modo che il linguaggio di query può essere ambiguo. Immagina di avere questo documento (e che si trattasse di un documento BSON valido):

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

E poi si è tentato di query con:

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

Se questo ritorno questo documento? Nel caso in quella stringa essere auto-confezionato in un ObjectId? Come si sa quando Mongo che può essere auto-boxed, e come per disambiguare in casi come questo documento?

Una possibile soluzione alternativa al tuo problema è quello di avere una serie di documenti incorporati come:

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

Questa è BSON valida, e sarà anche indicizzabile in modo più efficiente. Se si aggiunge un indice su answers, è possibile cercare in modo efficiente per corrispondenze esatte su questi documenti secondari; se si aggiunge un indice su answers.answer_id, allora si può cercare in modo efficiente dal ObjectId della risposta che state cercando (e così via).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top