2010-07-28 25 views
5

Cho phép nói rằng tôi có hai loại tài liệu được lưu trữ trong cơ sở dữ liệu CouchDB của tôi. Đầu tiên là loại thuộc tính được đặt thành liên hệ và thứ hai đến điện thoại. Loại tài liệu liên hệ có một thuộc tính khác được gọi là tên. Loại điện thoại có số thuộc tính và contact_id để có thể tham chiếu đến người liên hệ. Đây là một trong những kịch bản từ một đến nhiều khi một số liên lạc có thể có số điện thoại N (tôi biết rằng chúng có thể được nhúng trong tài liệu liên hệ duy nhất, nhưng tôi cần chứng minh một mối quan hệ với nhiều tài liệu khác nhau).Chế độ xem CouchDB soạn các đối tượng JSON với các mảng được nhúng từ hai tài liệu riêng biệt

dụ thô với Scott có 2 số điện thoại và Matt có 1 số:

{_id: "fc93f785e6bd8c44f14468828b001109", _rev: "1-fdc8d121351b0f5c6d7e288399c7a5b6", type: "phone", number: "123456", contact_id: "fc93f785e6bd8c44f14468828b00099f"} 
{_id: "fc93f785e6bd8c44f14468828b000f6a", _rev: "1-b2dd90295693dc395019deec7cbf89c7", type: "phone", number: "465789", contact_id: "fc93f785e6bd8c44f14468828b00099f"} 
{_id: "fc93f785e6bd8c44f14468828b00099f", _rev: "1-bd643a6b0e90c997a42d8c04c5c06af6", type: "contact", name: "Scott"} 
{_id: "16309fcd03475b9a2924c61d690018e3", _rev: "1-723b7c999111b116c353a4fdab11ddc0", type: "contact", name: "Matt"} 
{_id: "16309fcd03475b9a2924c61d69000aef", _rev: "3-67193f1bfa8ed21c68e3d35847e9060a", type: "phone", number: "789456", contact_id: "16309fcd03475b9a2924c61d690018e3"} 

chức năng bản đồ:

function(doc) { 
    if (doc.type == "contact") { 
    emit([doc._id, 1], doc); 
    } else if (doc.type == "phone") { 
    emit([doc.contact_id, 0], doc); 
    } 
} 

Giảm chức năng:

function(keys, values) { 
    var output = {}; 

    for(var elem in values) { 
    if(values[elem].type == "contact") { 
     output = { 
     "ID": values[elem]._id, 
     "Name": values[elem].name, 
     "Type": values[elem].type, 
     "Phones": [] 
     }; 
    } else if (values[elem].type == "phone") { 
     output.Phones.push({ 
     "Number": values[elem].number, 
     "Type": values[elem].type 
     }); 
    } 
    } 

    return output; 
} 

group_level được thiết lập để 1 vì các phím trong chức năng Bản đồ. Bây giờ tôi có thể nhận được liên lạc của tôi với điện thoại bao gồm ví dụ như thế này:

http://localhost:5984/testdb2/_design/testview/_view/tv1?group_level=1 

Hoặc tìm kiếm đối với một số tiếp xúc với startkey và endkey như thế này:

http://localhost:5984/testdb2/_design/testview/_view/tv1?group_level=1&startkey=[%22fc93f785e6bd8c44f14468828b00099f%22]&endkey=[%22fc93f785e6bd8c44f14468828b00099f%22,{}] 

Kết quả tìm kiếm chính xác làm thế nào tôi muốn - danh bạ sẽ có nhúng điện thoại theo một đến nhiều mối quan hệ. Và đây là câu hỏi: Đây có phải là cách thích hợp để sử dụng chức năng MapReduce trong CouchDB không? Có bất kỳ vấn đề hiệu suất đáng chú ý khi sử dụng phương pháp này không?

Trả lời

7

Nói chung bạn sử dụng ít dung lượng đĩa hơn nếu bạn không emit(...,doc).

Bạn có thể muốn xem xét lại việc có chức năng giảm. Nó thực sự không cần thiết để có được dữ liệu bạn cần. Ví dụ, một cái gì đó dọc theo các dòng sau đây có thể sử dụng không gian đĩa ít hơn và thực hiện tốt hơn nếu bạn có một số lượng lớn các bản ghi.

Ngoài ra, tôi tin rằng đó là chống lại hạt của CouchDB để xây dựng thêm dữ liệu trong một chức năng giảm hơn so với tài liệu của bạn chứa. Bạn không làm điều đó trong trường hợp này nhưng bạn đang theo dõi một khuôn mẫu có thể dẫn bạn vào rắc rối sau này. Nó được gọi là giảm vì một lý do. :-)

Vì vậy, một cái gì đó như thế này là nhiều cách CouchDB:

function(doc) { 
    if (doc.type == "contact") { 
    emit([doc._id, 0], { 
     "Name": doc.name, 
     "Type": doc.type 
    }); 
    } else if (doc.type == "phone") { 
    emit([doc.contact_id, 1], { 
     "Number": doc.number, 
     "Type": doc.type 
    }); 
    } 
}

Query nó cho một số liên lạc cụ thể như vậy:

http://localhost:5984/testdb2/_design/testview/_view/tv1? 
    startkey=[%22fc93f785e6bd8c44f14468828b00099f%22, 0] 
    &endkey=[%22fc93f785e6bd8c44f14468828b00099f%22,1] 

Cấp, bạn không nhận được kết quả trong cùng một Cấu trúc JSON như trước nhưng tôi tin rằng điều này thực hiện tốt hơn trong CouchDB.

0

Câu trả lời này là hoàn toàn khải huyền và giai thoại, nhưng đó chính xác là cách tôi đã làm việc với các mối quan hệ một-nhiều trong CouchDB. Nếu có bất kỳ vấn đề mở rộng quy mô nào, tôi chưa thấy chúng. (Nhưng tôi thừa nhận tôi đã không cố gắng quá khó để tìm thấy chúng.)

Mặc dù, trong chức năng bản đồ của bạn tại sao điện thoại của bạn được sắp xếp ra trước (0) trước số liên lạc (1)? Hàm reduce của bạn yêu cầu thứ tự ngược lại.

+0

Nó được sắp xếp như vậy bởi vì khi tôi truy cập trực tiếp chế độ xem thông qua trình duyệt, tôi sẽ phải chèn giảm dần = true vào url. – yojimbo87

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