2013-10-30 16 views
8

Tôi đang sử dụng MongoDB với dịch vụ REST nodejs để hiển thị dữ liệu của tôi được lưu trữ bên trong. Tôi có một câu hỏi về cách thẩm vấn dữ liệu của tôi sử dụng $ ref.

Dưới đây là một mẫu của một đối tượng, trong đó có một tham chiếu đến một đối tượng (xem chi tiết) trong bao phấn bộ sưu tập:

{ 
    "_id" : ObjectId("5962c7b53b6a02100a000085"), 
    "Title" : "test", 
    "detail" : { 
     "$ref" : "ObjDetail", 
     "$id" : ObjectId("5270c7b11f6a02100a000001") 
    }, 
    "foo" : bar 
} 

Trên thực tế, sử dụng Node.js và mô-đun MongoDB, tôi thực hiện như sau:

db.collection("Obj").findOne({"_id" : new ObjectID("5962c7b53b6a02100a000085"}, 
function(err, item) { 
    db.collection(item.$ref).findOne({"_id" : item.$id}, function(err,subItem){ 
     ... 
    }); 
}); 

Thực tế tôi tạo 2 truy vấn và nhận 2 đối tượng. Đó là một loại "tải chậm" (không chính xác nhưng gần như)

Câu hỏi của tôi rất đơn giản: có thể truy xuất toàn bộ biểu đồ đối tượng trong một truy vấn không?

Cảm ơn bạn

Trả lời

1

trả lời của Vladimir không phải là vẫn còn giá trị như phương pháp db.dereference đã bị xóa từ MongoDB Nodejs API:

https://www.mongodb.com/blog/post/introducing-nodejs-mongodb-20-driver

Các db đối tượng dụ đã được đơn giản hóa. Chúng tôi đã loại bỏ các phương pháp sau đây:

db.dereference do db tài liệu tham khảo được tán thành trong máy chủ

4

Không, bạn không thể.

Để giải quyết DBRef, ứng dụng của bạn phải thực hiện các truy vấn bổ sung để trả lại tài liệu được tham chiếu. Nhiều trình điều khiển có phương thức trợ giúp tạo thành truy vấn cho DBRef tự động. Các trình điều khiển không tự động giải quyết DBRefs vào tài liệu.

Từ tài liệu MongoDB http://docs.mongodb.org/manual/reference/database-references/.

+1

Và như xa như tôi biết tài xế nút-MongoDB bản địa không có một cách để giải quyết những refs cho bạn. – Brett

4

Có thể tìm nạp đối tượng mẹ cùng với $ ref bằng truy vấn MongoDB đơn lẻ không?

Không, không thể. Mongo không có sự hỗ trợ bên trong cho các lần chỉnh sửa, do đó, ứng dụng của bạn có thể điền vào chúng (xem Brett's answer).

Nhưng có thể tìm nạp đối tượng mẹ với tất cả các tham số của nó bằng một lệnh node.js không?

Có, có thể. Bạn có thể làm điều đó với Mongoose. Nó có hỗ trợ dân số được xây dựng trong ref. Bạn sẽ cần phải thay đổi mô hình dữ liệu của bạn một chút để làm cho nó hoạt động, nhưng nó là khá nhiều những gì bạn đang tìm kiếm. Tất nhiên, để làm như vậy Mongoose sẽ làm cho cùng hai truy vấn MongoDB mà bạn đã làm.

1

Không, rất ít trình điều khiển cho MongoDb bao gồm hỗ trợ đặc biệt cho DBRef. Có hai lý do:

  1. MongoDb không có bất kỳ lệnh đặc biệt nào để truy xuất tài liệu được tham chiếu có thể. Vì vậy, trình điều khiển làm thêm hỗ trợ là giả tạo dân cư các đối tượng kết quả.
  2. Càng nhiều, "kim loại trần" API, càng ít ý nghĩa. Trong thực tế, như. Bộ sưu tập MongoDb là lược đồ ít hơn, nếu trình điều khiển NodeJs đưa trở lại tài liệu chính với tất cả các tham chiếu đã nhận ra, nếu mã sau đó lưu tài liệu mà không phá vỡ các tham chiếu, nó sẽ dẫn đến một tài liệu phụ được nhúng. Tất nhiên, đó sẽ là một mớ hỗn độn.

Trừ khi giá trị trường của bạn thay đổi, tôi sẽ không bận tâm với loại DBRef và thay vào đó sẽ chỉ lưu trữ trực tiếp ObjectId.Như bạn có thể thấy, DBRef thực sự không cung cấp lợi ích ngoại trừ yêu cầu nhiều không gian đĩa trùng lặp cho mỗi tham chiếu, vì đối tượng phong phú hơn phải được lưu trữ cùng với thông tin loại của nó. Dù bằng cách nào, bạn cũng nên xem xét các chi phí không cần thiết của việc lưu trữ một chuỗi chứa các tài liệu của bộ sưu tập được tham chiếu.

Nhiều nhà phát triển và MongoDb, Inc. đã thêm lớp ánh xạ tài liệu đối tượng lên trên các trình điều khiển cơ bản hiện có. Một lựa chọn phổ biến cho MongoDb và Nodejs là Mongoose. Vì máy chủ MongoDb không có nhận thức thực sự về các tài liệu được tham chiếu, trách nhiệm của các tham chiếu sẽ di chuyển đến máy khách. Vì nó thường phổ biến hơn để tham khảo một bộ sưu tập cụ thể từ một tài liệu nhất định, Mongoose làm cho nó có thể xác định tham chiếu như là một lược đồ. Mongoose không phải là lược đồ ít hơn.

Nếu bạn chấp nhận việc sử dụng Lược đồ là hữu ích, thì Mongoose chắc chắn đáng xem. Nó có hiệu quả có thể lấy một loạt các tài liệu liên quan (từ một bộ sưu tập duy nhất) từ một tập hợp các tài liệu. Nó luôn luôn sử dụng trình điều khiển gốc, nhưng nó thường hoạt động cực kỳ hiệu quả và mất một số các drudgery ra khỏi kiến ​​trúc ứng dụng phức tạp hơn.

Tôi thực sự khuyên bạn nên xem phương pháp populate (here) để xem những gì nó có khả năng làm.

Demo  /* Demo would be a Mongoose Model that you've defined */ 
.findById(theObjectId) 
.populate('detail') 
.exec(function (err, doc) { 
    if (err) return handleError(err); 
    // do something with the single doc that was returned 
}) 

Nếu thay vì findById, mà luôn luôn trả về một tài liệu duy nhất, find được sử dụng, với populate, tất cả trả lại tài sản details văn sẽ được áp dụng tự động. Đó là thông minh quá rằng nó sẽ yêu cầu cùng một tài liệu tham chiếu nhiều lần.

Nếu bạn không sử dụng Mongoose, tôi khuyên bạn nên xem xét một lớp đệm để tránh tham gia tham chiếu phía máy khách khi có thể và sử dụng toán tử truy vấn $in nhiều nhất có thể.

+0

Cảm ơn bạn, tôi sẽ xem xét mongoose. –

1

tôi đạt được kết quả mong muốn với ví dụ tiếp theo:

collection.find({}, function (err, cursor) { 
    cursor.toArray(function (err, docs) { 
     var count = docs.length - 1; 
     for (i in docs) { 
      (function (docs, i) { 
       db.dereference(docs[i].ref, function(err, doc) { 
        docs[i].ref = doc; 
        if (i == count) { 
         (function (docs) { 
          console.log(docs); 
         })(docs); 
        } 
       }); 
      })(docs, i) 
     } 
    }); 
}); 

Không chắc chắn rằng nó là giải pháp tốt nhất của tốt nhất, nhưng nó là giải pháp đơn giản nhất mà tôi tìm thấy.

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