2012-01-24 24 views
5

Mở bài MongoDB finding nested elements này, tác giả khẳng định rằng cấu trúc tài liệu MongoDB là

 car : { "$ref" : "cars" , "$id" : { "$oid" : "4e8478ace4b0dea06288ad63"}} 

Khi tôi đã cố gắng để tạo lại vấn đề, tôi gặp một số hành vi kỳ lạ với chèn MongoDB

Khi chạy chèn trên dữ liệu mẫu ở trên, tôi đã nhận được lỗi sau

> db.sample.insert({car:{ "$ref" : "cars" , "$id" : { "$oid" : "4e8478ace4b0dea06288ad63"}}}) 
Tue Jan 24 14:09:07 uncaught exception: field names cannot start with $ [$oid] 

nó nói rằng tên trường không thể bắt đầu bằng $.

Nếu thats trường hợp, nó không nên làm việc nếu tôi loại bỏ $ từ oid và rời khỏi còn lại $ref & $id hoang sơ

> db.sample.insert({car:{ "$ref" : "cars" , "$id" : { "oid" : "4e8478ace4b0dea06288ad63"}}}) 
    > db.sample.find() 
{ "_id" : ObjectId("4f1e6fbc403aae757ec6dea5"), "car" : { "$ref" : "cars", "$id" : { "oid" : "4e8478ace4b0dea06288ad63" } } } 

đáng ngạc nhiên nó làm việc. Bây giờ nó chấp nhận các lĩnh vực bắt đầu với $

Ngoài ra khi tôi đã cố gắng truy vấn này

> db.sample.insert({ "$ref" : "cars" }) 
document to insert can't have $ fields 

tôi đã nhận lỗi trở lại.

Tôi không hiểu điều gì gây ra điều này? ai có một ý tưởng rõ ràng?

Trả lời

4

$id$ref là số nhận dạng đặc biệt được sử dụng cho dbrefs. Nếu không, tên trường bắt đầu bằng một số $ không được phép.

Tuy nhiên, tài liệu cấp một của bạn không được là chính dbref, do đó lỗi "tài liệu chèn không thể có trường $".

Tuy nhiên, dbrefs được cho phép dưới dạng subdocuments, ví dụ: (Từ official docs)

"name" : "Joe", 
"classes" : [ 
     { 
       "$ref" : "courses", 
       "$id" : ObjectId("4b0552b0f0da7d1eb6f126a1") 
     } 
] 

Bây giờ $oid không phải là một định danh đặc biệt, và không được phép vì $ có ngữ nghĩa đặc biệt: Hãy suy nghĩ về $inc. Đó là một toán tử, nhưng nếu cho phép $ tên trường, nó cũng có thể là tên của một trường.

Bạn phải cẩn thận khi sử dụng positional operator in updates:

Nhà điều hành theo vị trí không thể được kết hợp với một upsert vì nó đòi hỏi một phần tử mảng phù hợp. Nếu bản cập nhật của bạn dẫn đến chèn thì chữ "$" theo nghĩa đen sẽ được sử dụng làm tên trường.

+1

Vâng, đó là lý do ..cảm ơn bạn – RameshVel

+0

là có một cách để cơ hội DBRefs? – Backlit

+0

@Backlit: Tôi rất tiếc, tôi không hiểu câu hỏi. Bạn muốn thay đổi cú pháp của dbrefs? Đảm bảo bạn hiểu rằng bạn không phải sử dụng dbrefs - thực tế, thường không bắt buộc và tài liệu chính thức khuyên bạn nên sử dụng một liên kết trực tiếp đơn giản, như 'UserId: 423434'. – mnemosyn

1

$ref$id$db là các khóa hợp lệ duy nhất bắt đầu bằng ký hiệu đô la - chúng có liên quan đến quy ước DBRef.

Lý do bạn không thể sử dụng khóa của riêng mình bắt đầu bằng ký hiệu đô la là vì nó có Specialmeaning và nếu không sẽ tạo ra sự mơ hồ.

+0

Có cách nào xung quanh vấn đề này không? Ví dụ, thoát chúng? – devo

Các vấn đề liên quan