Hướng dẫn mongodb one-to-many relationship example - ví dụ về mối quan hệ một-nhiều mongodb

Tài liệu về nhà → Hướng dẫn sử dụng MongoDBMongoDB Manual

Trang này mô tả một mô hình dữ liệu sử dụng các tài liệu nhúng để mô tả mối quan hệ một-nhiều giữa dữ liệu được kết nối. Nhúng dữ liệu được kết nối vào một tài liệu duy nhất có thể giảm số lượng hoạt động đọc cần thiết để có được dữ liệu. Nói chung, bạn nên cấu trúc lược đồ của mình để ứng dụng của bạn nhận được tất cả thông tin cần thiết trong một thao tác đọc.

Hãy xem xét các ví dụ sau đây ánh xạ người bảo trợ và nhiều mối quan hệ địa chỉ. Ví dụ minh họa lợi thế của việc nhúng trong việc tham khảo nếu bạn cần xem nhiều thực thể dữ liệu trong bối cảnh của một thực thể khác. Trong mối quan hệ một-nhiều này giữa dữ liệu patronaddress, patron có nhiều thực thể address.

Trong mô hình dữ liệu được chuẩn hóa, các tài liệu address chứa tham chiếu đến tài liệu patron.

// patron document
{
_id: "joe",
name: "Joe Bookreader"
}
// address documents
{
patron_id: "joe", // reference to patron document
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
}
{
patron_id: "joe",
street: "1 Some Other Street",
city: "Boston",
state: "MA",
zip: "12345"
}

Nếu ứng dụng của bạn thường xuyên truy xuất dữ liệu address với thông tin

{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}
2, thì ứng dụng của bạn cần phát hành nhiều truy vấn để giải quyết các tài liệu tham khảo. Một lược đồ tối ưu hơn sẽ là nhúng các thực thể dữ liệu address vào dữ liệu patron, như trong tài liệu sau:

{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}

Với mô hình dữ liệu được nhúng, ứng dụng của bạn có thể lấy thông tin bảo trợ hoàn chỉnh bằng một truy vấn.

Một vấn đề tiềm năng với mẫu tài liệu nhúng là nó có thể dẫn đến các tài liệu lớn, đặc biệt là nếu trường nhúng không bị ràng buộc. Trong trường hợp này, bạn có thể sử dụng mẫu tập hợp con để chỉ truy cập dữ liệu được yêu cầu bởi ứng dụng, thay vì toàn bộ tập hợp dữ liệu được nhúng.embedded document pattern is that it can lead to large documents, especially if the embedded field is unbounded. In this case, you can use the subset pattern to only access data which is required by the application, instead of the entire set of embedded data.

Xem xét một trang web thương mại điện tử có danh sách các đánh giá cho một sản phẩm:

{
"_id": 1,
"name": "Super Widget",
"description": "This is the most useful item in your toolbox.",
"price": { "value": NumberDecimal("119.99"), "currency": "USD" },
"reviews": [
{
"review_id": 786,
"review_author": "Kristina",
"review_text": "This is indeed an amazing widget.",
"published_date": ISODate("2019-02-18")
},
{
"review_id": 785,
"review_author": "Trina",
"review_text": "Nice product. Slow shipping.",
"published_date": ISODate("2019-02-17")
},
...
{
"review_id": 1,
"review_author": "Hans",
"review_text": "Meh, it's okay.",
"published_date": ISODate("2017-12-06")
}
]
}

Các đánh giá được sắp xếp theo thứ tự thời gian ngược. Khi người dùng truy cập trang sản phẩm, ứng dụng sẽ tải mười đánh giá gần đây nhất.

Thay vì lưu trữ tất cả các đánh giá với sản phẩm, bạn có thể chia bộ sưu tập thành hai bộ sưu tập:

  • Bộ sưu tập

    {
    "_id": "joe",
    "name": "Joe Bookreader",
    "addresses": [
    {
    "street": "123 Fake Street",
    "city": "Faketon",
    "state": "MA",
    "zip": "12345"
    },
    {
    "street": "1 Some Other Street",
    "city": "Boston",
    "state": "MA",
    "zip": "12345"
    }
    ]
    }
    5 lưu trữ thông tin về từng sản phẩm, bao gồm mười đánh giá gần đây nhất của sản phẩm:

    {
    "_id": 1,
    "name": "Super Widget",
    "description": "This is the most useful item in your toolbox.",
    "price": { "value": NumberDecimal("119.99"), "currency": "USD" },
    "reviews": [
    {
    "review_id": 786,
    "review_author": "Kristina",
    "review_text": "This is indeed an amazing widget.",
    "published_date": ISODate("2019-02-18")
    }
    ...
    {
    "review_id": 777,
    "review_author": "Pablo",
    "review_text": "Amazing!",
    "published_date": ISODate("2019-02-16")
    }
    ]
    }

  • Bộ sưu tập

    {
    "_id": "joe",
    "name": "Joe Bookreader",
    "addresses": [
    {
    "street": "123 Fake Street",
    "city": "Faketon",
    "state": "MA",
    "zip": "12345"
    },
    {
    "street": "1 Some Other Street",
    "city": "Boston",
    "state": "MA",
    "zip": "12345"
    }
    ]
    }
    6 lưu trữ tất cả các đánh giá. Mỗi đánh giá chứa một tham chiếu đến sản phẩm mà nó được viết.

    {
    "review_id": 786,
    "product_id": 1,
    "review_author": "Kristina",
    "review_text": "This is indeed an amazing widget.",
    "published_date": ISODate("2019-02-18")
    }
    {
    "review_id": 785,
    "product_id": 1,
    "review_author": "Trina",
    "review_text": "Nice product. Slow shipping.",
    "published_date": ISODate("2019-02-17")
    }
    ...
    {
    "review_id": 1,
    "product_id": 1,
    "review_author": "Hans",
    "review_text": "Meh, it's okay.",
    "published_date": ISODate("2017-12-06")
    }

Bằng cách lưu trữ mười đánh giá gần đây nhất trong bộ sưu tập

{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}
5, chỉ có tập hợp con yêu cầu của dữ liệu tổng thể được trả về trong cuộc gọi cho bộ sưu tập
{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}
5. Nếu người dùng muốn xem các đánh giá bổ sung, ứng dụng gọi điện đến bộ sưu tập
{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}
6.

Mẹo

Khi xem xét nơi phân chia dữ liệu của bạn, phần dữ liệu được truy cập thường xuyên nhất trong bộ sưu tập mà ứng dụng tải trước. Trong ví dụ này, lược đồ được chia ở mười đánh giá vì đó là số lượng đánh giá có thể hiển thị trong ứng dụng theo mặc định.

Mẹo

Khi xem xét nơi phân chia dữ liệu của bạn, phần dữ liệu được truy cập thường xuyên nhất trong bộ sưu tập mà ứng dụng tải trước. Trong ví dụ này, lược đồ được chia ở mười đánh giá vì đó là số lượng đánh giá có thể hiển thị trong ứng dụng theo mặc định.

Xem thêm:

Sử dụng các tài liệu nhỏ hơn chứa dữ liệu được truy cập thường xuyên hơn làm giảm kích thước tổng thể của bộ làm việc. Các tài liệu nhỏ hơn này dẫn đến hiệu suất đọc được cải thiện cho dữ liệu mà ứng dụng truy cập thường xuyên nhất.

Tuy nhiên, mẫu tập hợp con dẫn đến sao chép dữ liệu. Trong ví dụ, các đánh giá được duy trì trong cả bộ sưu tập

{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}
5 và bộ sưu tập
{
"_id": 1,
"name": "Super Widget",
"description": "This is the most useful item in your toolbox.",
"price": { "value": NumberDecimal("119.99"), "currency": "USD" },
"reviews": [
{
"review_id": 786,
"review_author": "Kristina",
"review_text": "This is indeed an amazing widget.",
"published_date": ISODate("2019-02-18")
},
{
"review_id": 785,
"review_author": "Trina",
"review_text": "Nice product. Slow shipping.",
"published_date": ISODate("2019-02-17")
},
...
{
"review_id": 1,
"review_author": "Hans",
"review_text": "Meh, it's okay.",
"published_date": ISODate("2017-12-06")
}
]
}
1. Các bước bổ sung phải được thực hiện để đảm bảo rằng các đánh giá phù hợp giữa mỗi bộ sưu tập. Ví dụ: khi khách hàng chỉnh sửa đánh giá của họ, ứng dụng có thể cần thực hiện hai hoạt động ghi: một để cập nhật bộ sưu tập
{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}
5 và một để cập nhật bộ sưu tập
{
"_id": 1,
"name": "Super Widget",
"description": "This is the most useful item in your toolbox.",
"price": { "value": NumberDecimal("119.99"), "currency": "USD" },
"reviews": [
{
"review_id": 786,
"review_author": "Kristina",
"review_text": "This is indeed an amazing widget.",
"published_date": ISODate("2019-02-18")
},
{
"review_id": 785,
"review_author": "Trina",
"review_text": "Nice product. Slow shipping.",
"published_date": ISODate("2019-02-17")
},
...
{
"review_id": 1,
"review_author": "Hans",
"review_text": "Meh, it's okay.",
"published_date": ISODate("2017-12-06")
}
]
}
1.

Bạn cũng phải triển khai logic trong ứng dụng của mình để đảm bảo rằng các đánh giá trong bộ sưu tập

{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}
5 luôn là mười đánh giá gần đây nhất cho sản phẩm đó.

  • Ngoài các đánh giá sản phẩm, mẫu tập hợp con cũng có thể phù hợp để lưu trữ:

  • Nhận xét trên một bài đăng trên blog, khi bạn chỉ muốn hiển thị các nhận xét gần đây nhất hoặc được đánh giá cao nhất theo mặc định.