Вопрос

Используя драйвер Pimongo, чтобы подключить Python к MongoDB, почему использование экземпляра ObjectID в качестве ключа для встроенного документа повышает ошибку InvalidDocument?

Я пытаюсь связать документы с использованием ObjectIds и не могу понять, почему я хотел бы преобразовать их в строки, когда те, которые создаются автоматически для драйвера, 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')

На практике связанные идентификаторы представляют документы, которые содержат вопросы, и значения в словаре здесь, которые представляют собой, как «Otherstuff», например, будут представлять ответы этого отдельного документа на этот конкретный вопрос.

Есть ли причина применения объектов, подобных этому, не будет кодировать в BSON, а затем терпит неудачу? Невозможно ли гнездировать объекты в таких документах, как это, чтобы перекрестные ссылки? Я неправильно понял их цель?

Это было полезно?

Решение

А Bson Spec Диктует, что ключи должны быть строками, поэтому Pimongo прав, чтобы отвергнуть это как недопустимый документ (и независимо от того, на каком уровне объект ID использовался в качестве ключа, будь то на верхнем уровне или в встроенном документе). Это необходимо, среди прочих причин, так что язык запросов может быть однозначным. Представьте, что у вас был этот документ (и что это был действительный документ BSON):

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

А потом вы попытались запросить:

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

Должен ли это вернуть этот документ? Должна ли эта строка быть автоматической боксами в ObjectId? Как Монго узнает, когда это может быть автоматическим боксом, и как устранение устранения устранения в таких случаях, как этот документ?

Возможное альтернативное решение вашей проблемы состоит в том, чтобы иметь множество встроенных документов, таких как:

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

Это действительный BSON, а также будет индексируется более эффективно. Если вы добавите индекс на answers, вы можете эффективно искать для точных совпадений в этих подразделениях; Если вы добавите индекс на answers.answer_id, тогда вы можете эффективно искать ObjectId ответа, который вы ищете (и так далее).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top