2012-01-10 1 views
1

pymongo 드라이버를 사용하여 mongodb에 파이썬을 연결하면 임베디드 문서의 키로 ObjectId 인스턴스를 사용하면 InvalidDocument 오류가 발생합니다.pymongo 임베디드 objectIds, InvalidDocumentError 저장

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

링크 된 ID는 질문이 포함 된 문서를 나타내며, 사전에 값이 여기에 해당 질문이 개별 문서의 응답을 나타내는 것, 예를 들어 'otherstuff'로 키가.

이와 같은 objectids를 적용하는 이유가 bson으로 인코딩되지 않고 실패 할 이유가 있습니까? 이 같은 문서 내의 ObjectId를 상호 참조로 중첩하는 것은 불가능합니까? 나는 그 (것)들의 목적을 오해 했는가?

답변

6

BSON spec은 키가 문자열이어야하므로 PyMongo가 이것을 잘못된 문서로 거부 할 수 있다고 명령합니다 (ObjectId가 키로 사용 된 레벨에 상관없이 최상위 레벨 또는 포함 된 레벨에 관계 없음). 문서). 다른 이유로 쿼리 언어를 명확하게 지정할 수 있어야합니다. 이 문서를 가지고 상상 (그리고 유효한 BSON 문서라고) :

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

을 그리고 당신이 쿼리를 시도 :

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

점검이 수익이 문서? 해당 문자열을 ObjectId에 자동으로 입력해야합니까? Mongo는 이것이 자동 박스가 될 수있는시기와이 문서와 같은 경우 명확하게 구분하는 방법을 어떻게 알 수 있습니까?

문제에 대한 가능한 대안 솔루션과 같은 포함 된 문서의 배열하는 것입니다 :

{ 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로 효율적으로 검색 할 수 있습니다.