Hướng dẫn can mongodb model many to many? - mô hình mongodb có thể nhiều thành nhiều không?

Trong chuyện ngoại tình của loài người, thật tệ khi có nhiều mối quan hệ. Tuy nhiên, trong khoa học máy tính, nó là tốt.

Gần đây tôi đã thêm thẻ vào bài viết trên blog. Mối quan hệ thẻ blog này là một mô hình mối quan hệ nhiều người nhiều cổ điển. Tài liệu MongoDB chỉ viết về cách mô hình hóa mối quan hệ một-nhiều. Vì vậy, tôi sẽ chỉ cho bạn cách tôi mô hình hóa mối quan hệ nhiều đến nhiều ở MongoDB, trong đó dữ liệu của trang web này được lưu trữ.

Show

Điều kiện tiên quyết

Tôi cho rằng bạn đã cài đặt MongoDB trên máy tính của mình và có kiến ​​thức cơ bản về NoQuery.

Theo văn bản này, MongoDB của tôi là phiên bản 5.0.4. Tôi tin rằng phiên bản 3.0 trở lên hoạt động tốt với tất cả các lệnh được hiển thị bên dưới.

Nếu bạn chưa cài đặt MongoDB, vui lòng tham khảo Hướng dẫn cài đặt của họ.

Người mẫu

Ý tưởng về mối quan hệ thẻ blog được mô tả như dưới đây:

Hướng dẫn can mongodb model many to many? - mô hình mongodb có thể nhiều thành nhiều không?

Các mô hình dưới đây không chính xác là cách cơ sở dữ liệu của tôi được mô hình hóa. Nó chỉ là để cho bạn thấy như một hướng dẫn.

Blog
{
	id: Integer,
	title: String,
	tags: Array of Tag ID
}
Tag
{
	id: Integer,
	name: String,
}

Tôi đã thêm ID trường để người đọc có thể sao chép, dán và chạy các truy vấn tương tự. Nhưng trong ứng dụng thực tế, ObjectID _ID được gán cho mọi tài liệu sẽ thực hiện trên thực tế nó được ưa thích.

Bình thường hóa V.S. Nhúng

Trong mô hình ở trên, tôi đã áp dụng mô hình dữ liệu được chuẩn hóa, còn được gọi là mô hình tham chiếu. Trong mô hình dữ liệu được chuẩn hóa, các tài liệu lưu trữ tham chiếu đến các tài liệu khác, được sử dụng để liên kết hai tài liệu. Thông thường đối tượng của tài liệu được sử dụng làm tài liệu tham khảo.

Nguồn: MongoDB

Cách khác của mô hình hóa là mô hình dữ liệu nhúng. Trong mô hình này, các mối quan hệ của dữ liệu được lưu trữ dưới dạng tài liệu phụ bên trong một tài liệu duy nhất.

Nguồn: MongoDB

Cách khác của mô hình hóa là mô hình dữ liệu nhúng. Trong mô hình này, các mối quan hệ của dữ liệu được lưu trữ dưới dạng tài liệu phụ bên trong một tài liệu duy nhất.

Nói chung, trong các mối quan hệ một-nhiều hoặc nhiều đến nhiều, mô hình dữ liệu được chuẩn hóa là thích hợp hơn vì nó có thể lưu lượng dữ liệu và thay đổi trên tài liệu được tham chiếu cập nhật tất cả các tài liệu tham khảo liên quan đến dữ liệu. Ngay cả đối với mối quan hệ một-một trong đó liên kết giữa hai tài liệu rất yếu hoặc rất tinh tế như thông tin thẻ tín dụng cho người dùng, bạn có thể sử dụng mô hình dữ liệu được chuẩn hóa.

Dữ liệu hạt giống

% brew services start mongodb-community # on version 5
% mongosh

Ví dụ, tôi sẽ sử dụng cơ sở dữ liệu có tên M2M, là viết tắt của nhiều-nhiều và hai blog và thẻ bộ sưu tập. Để lưu trữ dữ liệu hạt giống vào cơ sở dữ liệu, hãy khởi động MongoDB của bạn và đăng nhập vào vỏ của nó:

> use m2m
> db.tags.insertMany([
	{id: 0, name: 'Node.js'},
	{id: 1, name: 'MongoDB'},
	{id: 2, name: 'React.js'}
])
> db.blogs.insertMany([
	{id: 0, title: 'Mongoose', tags: [0, 1]},
	{id: 1, title: 'GraphQL', tags: [1, 2]},
	{id: 2, title: 'ReactDOMServer', tags: [0, 2]}
])

Và tạo ba tài liệu cho mỗi bộ sưu tập với Chèn chèn ():

> db.tags.find()
// Output
[
  {_id: ObjectId("62…bd"), id: 0, name: 'Node.js'},
  {_id: ObjectId("62…be"), id: 1, name: 'MongoDB'},
  {_id: ObjectId("62…bf"), id: 2, name: 'React.js'}
]

> db.blogs.find()
// Output
[
  {_id: ObjectId("62…c0"), id: 0, title: 'Mongoose', tags: [0, 1]},
  {_id: ObjectId("62…c1"), id: 1, title: 'GraphQL', tags: [1, 2]},
  {_id: ObjectId("62…c2"), id: 2, title: 'ReactDOMServer', tags: [0, 2]}
]

Vui lòng đảm bảo rằng những dữ liệu đó được lưu trữ với db.collection.find ():

Từ giờ trở đi trong bài đăng này, tôi sẽ loại bỏ trường _id khỏi các đầu ra.

Truy vấn

Để tính toán các tài liệu thông qua nhiều quy trình, chúng tôi sử dụng các hoạt động tổng hợp trong MongoDB.

  • Chúng tôi đã sử dụng db.collection.find () ở trên và hàm này chấp nhận ba phương thức truy vấn, trình chiếu và con trỏ đối số.: determines the filter which documents are to be returned.
  • Truy vấn: Xác định bộ lọc mà tài liệu sẽ được trả về.: determines which fields are returned in the matching documents.
  • Dự đoán: Xác định các trường nào được trả về trong các tài liệu phù hợp.: determines optional computation such as sort, limit, skip.

Phương pháp con trỏ: Xác định tính toán tùy chọn như sắp xếp, giới hạn, bỏ qua.

> db.blogs.find({tags: 1}, {_id: 0}, {sort: {id: -1}, skip: 1, limit: 1});
// Output
[
  {id: 0, title: 'Mongoose', tags: [0, 1]}
]

Vui lòng thử một truy vấn:

> db.blogs.aggregate([
  {$match: {tags: 1}},
  {$project: {_id: 0}},
  {$sort: {id: -1}},
  {$skip: 1},
  {$limit: 1}
])
// Output
[
  {id: 0, title: 'Mongoose', tags: [0, 1]}
]

Đây là một truy vấn đơn giản, vì vậy nó không phải là một vấn đề. Nhưng khi truy vấn trở nên phức tạp, nó sẽ. Và một số truy vấn, giống như kết nối dữ liệu bài đăng trên blog với dữ liệu thẻ là không thể. Phương thức Find () ở trên có thể được viết lại bằng db.collection.aggregate () như:

Hướng dẫn can mongodb model many to many? - mô hình mongodb có thể nhiều thành nhiều không?

Tham gia với $ Tra cứu

Trong cơ sở dữ liệu quan hệ SQL, chúng tôi sử dụng tham gia để liên quan đến hai bảng. Trong MongoDB, chúng tôi sử dụng $ Tra cứu để có được kết quả tương tự.

> db.blogs.aggregate([
	{$lookup: {from: 'tags', localField: 'tags', foreignField: 'id', as: 'tags'}},
])
// Output
[
  {
  	id: 0,
    title: 'Mongoose',
    tags: [{id: 0, name: 'Node.js'}, {id: 1, name: 'MongoDB'}]
  },
  {
    id: 1,
    title: 'GraphQL',
    tags: [{id: 1, name: 'MongoDB'}, {id: 2, name: 'React.js'}]
  },
  {
    id: 2,
    title: 'ReactDOMServer',
    tags: [{id: 0, name: 'Node.js'}, {id: 2, name: 'React.js'}]
  }
]

Bây giờ, hãy để thử một lần tra cứu $ đơn giản:

ID của các thẻ trong tài liệu blog được thay thế bằng các tài liệu thẻ.

Việc tra cứu $ ở trên là một chút khó khăn. Khi Localfield là một mảng, bạn có thể tham gia các tài liệu chống lại trường nước ngoài vô hướng. Để biết chi tiết, vui lòng tham khảo sử dụng $ Tra cứu với một mảng.

Hướng dẫn can mongodb model many to many? - mô hình mongodb có thể nhiều thành nhiều không?

Lọc theo thẻ

> db.blogs.aggregate([
	{$match: {tags: 0}},
	{$lookup: {from: 'tags', localField: 'tags', foreignField: 'id', as: 'tags'}}
])
// Output
[
  {
  	id: 0,
    title: 'Mongoose',
    tags: [{id: 0, name: 'Node.js'}, {id: 1, name: 'MongoDB'}]
  },
  {
    id: 2,
    title: 'ReactDOMServer',
    tags: [{id: 0, name: 'Node.js'}, {id: 2, name: 'React.js'}]
  }
]

OK, chúng tôi hiểu cơ bản của $ tra cứu. Tiếp theo, chúng tôi muốn chỉ tìm thấy các bài đăng trên blog được gắn thẻ Node.js.

Xem rằng chúng tôi chỉ nhận được các bài đăng trên blog được gắn thẻ Node.js (ID: 0) và bài đăng trên blog GraphQL được lọc ra.

Hướng dẫn can mongodb model many to many? - mô hình mongodb có thể nhiều thành nhiều không?

$ Tra cứu đường ống

Bây giờ hãy tưởng tượng một tình huống mà bạn không muốn cho mọi người thấy một số thẻ nhất định, hiện tại nó hiện đang được thử nghiệm. Hãy để nói rằng bạn là người mới để React.js. Mặc dù bạn gắn thẻ các bài viết bằng thẻ đó, nhưng bạn không muốn hiển thị nó trong kết quả truy vấn. Để làm điều này, chúng tôi vượt qua đường ống ở giai đoạn tra cứu $.

> db.blogs.aggregate([
  {$lookup: {
    from: 'tags',
    localField: 'tags',
    foreignField: 'id',
    as: 'tags',
    pipeline: [
      {$match: {name: {$ne: 'React.js'}}}
    ]
  }}
])
// Output
[
  {
    id: 0,
    title: 'Mongoose',
    tags: [{id: 0, name: 'Node.js'}, {id: 1, name: 'MongoDB'}]
  },
  {
    id: 1,
    title: 'GraphQL',
    tags: [{id: 1, name: 'MongoDB'}]
  },
  {
    id: 2,
    title: 'ReactDOMServer',
    tags: [{id: 0, name: 'Node.js'}]
  }
]

Truy vấn dưới đây là cách bạn làm điều đó:

React.js được xóa khỏi danh sách thẻ được nối với các tài liệu.

Hướng dẫn can mongodb model many to many? - mô hình mongodb có thể nhiều thành nhiều không?

Đếm bài đăng được gắn thẻ

Ví dụ tuyệt vời mà bạn muốn hiển thị số lượng bài đăng được gắn thẻ từ khóa nhất định là thẻ của trang web này.

{
	id: Integer,
	name: String,
}
0

Sự kết luận

Để tạo mối quan hệ nhiều thứ trong cơ sở dữ liệu quan hệ, chúng tôi phải tạo một bảng trung gian như blog_TAG lưu trữ ID blog và ID thẻ trong các hàng. Trong MongoDB, là một cơ sở dữ liệu định hướng tài liệu, không cần thiết.

Bạn có thể có bất kỳ trường hợp nào mà chúng tôi đã giành được các truy vấn thực hiện ở MongoDB mà chúng tôi từng làm trong MySQL không? Thành thật mà nói, tôi không thể trả lời câu hỏi đó. "Cái nào tốt hơn, MongoDB hay MySQL?" Tôi cũng không thể trả lời câu hỏi đó.

Chúng tôi ước rằng có thể có một giải pháp một trong tất cả, nhưng mọi thứ đều đánh đổi trong phát triển và kỹ thuật. Giải pháp tốt nhất phụ thuộc vào cách chúng ta mô hình hóa dữ liệu, nói cách khác, vào chúng ta, thay vì vào công nghệ.

Các truy vấn mẫu mực được hiển thị ở trên, và mô hình nhiều đến nhiều mà tôi đã áp dụng, chỉ là một cách tiếp cận. Bạn có thể nghĩ ra ý tưởng tốt hơn.

Và để có được hầu hết MongoDB, chúng ta sẽ quen với nó, thay vì hiểu nó.

Tài nguyên

  • MongoDB
  • Mô hình mối quan hệ một-nhiều nhiều với tài liệu tham khảo tài liệu
  • Hoạt động tổng hợp
  • MongoDB Mối quan hệ nhiều đến nhiều với các ví dụ Mongoose

Những hạn chế của MongoDB là gì?

Kích thước tài liệu BSON tối đa là 16 megabyte. Kích thước tài liệu tối đa giúp đảm bảo rằng một tài liệu duy nhất không thể sử dụng lượng RAM quá mức hoặc, trong quá trình truyền, lượng băng thông quá mức. Để lưu trữ các tài liệu lớn hơn kích thước tối đa, MongoDB cung cấp API GridFS.. The maximum document size helps ensure that a single document cannot use excessive amount of RAM or, during transmission, excessive amount of bandwidth. To store documents larger than the maximum size, MongoDB provides the GridFS API.

Những tình huống nào là MongoDB không phù hợp?

Một trong những nhược điểm của MongoDB là nó không hỗ trợ các giao dịch. Mặc dù ngày càng ít ứng dụng yêu cầu giao dịch, nhưng vẫn có một số ứng dụng cần giao dịch để cập nhật nhiều tài liệu/bộ sưu tập. Nếu đó là một chức năng cần thiết cho nhóm của bạn, không nên sử dụng MongoDB.it doesn't support transactions. Though fewer and fewer applications are requiring transactions, there are still some that need transactions in order to update multiple documents/collections. If that's a necessary function for your team, MongoDB should not be used.

MongoDB có thể xử lý hàng triệu hồ sơ không?

Làm việc với MongoDB và Elaticsearch là một quyết định chính xác để xử lý hàng triệu hồ sơ trong thời gian thực.Các cấu trúc và khái niệm này có thể được áp dụng cho các bộ dữ liệu lớn hơn và cũng sẽ hoạt động rất tốt.. These structures and concepts could be applied to larger datasets and will work extremely well too.

MongoDB có tốt cho các dự án lớn không?

MongoDB cũng có thể xử lý khối lượng lớn và có thể mở rộng cả theo chiều dọc hoặc chiều ngang để phù hợp với tải dữ liệu lớn..

MongoDB có thể xử lý bao nhiêu yêu cầu?

Atlas miễn phí cho phép 500 kết nối và tổng cộng 500 bộ sưu tập (100 cơ sở dữ liệu).500 connections and a max of 500 collections (100 databases) in total.

MongoDB đại diện cho một

Mối quan hệ một-nhiều (1: n) mô tả mối quan hệ mà một bên có thể có nhiều hơn một mối quan hệ trong khi mối quan hệ ngược chỉ có thể là một mặt.Một ví dụ là một blog mà một blog có thể có nhiều nhận xét nhưng một bình luận chỉ liên quan đến một blog.The 1:N relationship describes a relationship where one side can have more than one relationship while the reverse relationship can only be single sided. An example is a Blog where a blog might have many Comments but a Comment is only related to a single Blog.