Mongodb tra cứu một đến nhiều

MongoDB là một trong những cơ sở dữ liệu phổ biến nhất cho các ứng dụng hiện đại. Nó cho phép cách tiếp cận mô hình hóa dữ liệu linh hoạt hơn so với cơ sở dữ liệu SQL truyền thống. Các nhà phát triển có thể xây dựng ứng dụng nhanh hơn nhờ tính linh hoạt này và cũng có nhiều tùy chọn triển khai, từ cung cấp MongoDB Atlas trên đám mây cho đến Phiên bản cộng đồng nguồn mở

MongoDB lưu trữ từng bản ghi dưới dạng tài liệu với các trường. Các trường này có thể có nhiều loại linh hoạt và thậm chí có thể có các tài liệu khác làm giá trị. Mỗi tài liệu là một phần của bộ sưu tập — hãy nghĩ đến một bảng nếu bạn đến từ một mô hình quan hệ. Khi bạn đang cố gắng tạo một tài liệu trong một nhóm chưa tồn tại, MongoDB sẽ tạo nó một cách nhanh chóng. Không cần tạo bộ sưu tập và chuẩn bị lược đồ trước khi bạn thêm dữ liệu vào đó

MongoDB cung cấp MongoDB Query Language để thực hiện các thao tác trong cơ sở dữ liệu. Khi truy xuất dữ liệu từ một bộ sưu tập tài liệu, chúng tôi có thể tìm kiếm theo trường, áp dụng bộ lọc và sắp xếp kết quả theo tất cả các cách mà chúng tôi mong muốn. Ngoài ra, hầu hết các ngôn ngữ đều có ánh xạ quan hệ đối tượng gốc, chẳng hạn như Mongoose trong JavaScript và Mongoid trong Ruby

Việc thêm thông tin liên quan từ các bộ sưu tập khác vào dữ liệu được trả về không phải lúc nào cũng nhanh chóng hoặc trực quan. Hãy tưởng tượng chúng ta có hai bộ sưu tập. một tập hợp người dùng và một tập hợp các sản phẩm. Chúng tôi muốn truy xuất danh sách tất cả người dùng và hiển thị danh sách các sản phẩm mà từng người đã mua. Chúng tôi muốn thực hiện điều này trong một truy vấn duy nhất để đơn giản hóa mã và giảm các giao dịch dữ liệu giữa máy khách và cơ sở dữ liệu

Chúng tôi sẽ thực hiện việc này với phép nối ngoài bên trái của bảng Người dùng và Sản phẩm trong cơ sở dữ liệu SQL. Tuy nhiên, MongoDB không phải là cơ sở dữ liệu SQL. Tuy nhiên, điều này không có nghĩa là không thể thực hiện nối dữ liệu — chúng chỉ trông hơi khác so với cơ sở dữ liệu SQL. Trong bài viết này, chúng tôi sẽ xem xét các chiến lược mà chúng tôi có thể sử dụng để nối dữ liệu trong MongoDB

Tham gia dữ liệu trong MongoDB

Hãy bắt đầu bằng cách thảo luận về cách chúng ta có thể nối dữ liệu trong MongoDB. Có hai cách để thực hiện phép nối. sử dụng toán tử

SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
0 và không chuẩn hóa. Ở phần sau của bài viết này, chúng ta cũng sẽ xem xét một số lựa chọn thay thế để thực hiện phép nối dữ liệu

Sử dụng Toán tử tra cứu $

Bắt đầu với MongoDB phiên bản 3. 2, ngôn ngữ truy vấn cơ sở dữ liệu bao gồm toán tử tra cứu $. Tra cứu MongoDB xảy ra như một giai đoạn trong đường dẫn tổng hợp. Toán tử này cho phép chúng tôi tham gia hai bộ sưu tập trong cùng một cơ sở dữ liệu. Nó thêm một giai đoạn khác vào quy trình truy xuất dữ liệu một cách hiệu quả, tạo ra một trường mảng mới có các phần tử là các tài liệu phù hợp từ bộ sưu tập đã tham gia. Hãy xem nó trông như thế nào

Bắt đầu với MongoDB phiên bản 3. 2, ngôn ngữ truy vấn cơ sở dữ liệu bao gồm toán tử

SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
0. Tra cứu MongoDB xảy ra như một giai đoạn trong đường dẫn tổng hợp. Toán tử này cho phép chúng tôi tham gia hai bộ sưu tập trong cùng một cơ sở dữ liệu. Nó thêm một giai đoạn khác vào quy trình truy xuất dữ liệu một cách hiệu quả, tạo ra một trường mảng mới có các phần tử là các tài liệu phù hợp từ bộ sưu tập đã tham gia. Hãy xem nó trông như thế nào

db.users.aggregate([{$lookup: 
    {
     from: "products", 
     localField: "product_id", 
     foreignField: "_id", 
     as: "products"
    }
}])

Bạn có thể thấy rằng chúng tôi đã sử dụng toán tử

SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
0 trong một cuộc gọi tổng hợp đến bộ sưu tập của người dùng. Toán tử lấy một đối tượng tùy chọn có các giá trị tiêu biểu cho bất kỳ ai đã làm việc với cơ sở dữ liệu SQL. Vì vậy,
SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
0 là tên của bộ sưu tập phải có trong cùng một cơ sở dữ liệu và
SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
1 là trường chúng tôi so sánh với
SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
2 trong cơ sở dữ liệu đích. Khi chúng tôi có tất cả các sản phẩm phù hợp, chúng tôi thêm chúng vào một mảng được đặt tên bởi thuộc tính

Cách tiếp cận này tương đương với truy vấn SQL trông như thế này, sử dụng truy vấn con

SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);

Hoặc như thế này, sử dụng phép nối trái

SELECT *
FROM users
LEFT JOIN products
ON user.product_id = products._id

Mặc dù hoạt động này thường có thể đáp ứng nhu cầu của chúng tôi, toán tử

SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
0 đưa ra một số nhược điểm. Đầu tiên, điều quan trọng là chúng ta sử dụng
SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
0 ở giai đoạn nào của truy vấn. Có thể khó xây dựng các loại, bộ lọc hoặc kết hợp phức tạp hơn trên dữ liệu của chúng tôi trong các giai đoạn sau của quy trình tổng hợp nhiều giai đoạn. Thứ hai,
SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
0 là một hoạt động tương đối chậm, làm tăng thời gian truy vấn của chúng tôi. Mặc dù chúng tôi chỉ gửi một truy vấn duy nhất trong nội bộ, nhưng MongoDB thực hiện nhiều truy vấn để đáp ứng yêu cầu của chúng tôi

Sử dụng Chuẩn hóa trong MongoDB

Để thay thế cho việc sử dụng toán tử ________ 10, chúng tôi có thể chuẩn hóa dữ liệu của bạn. Cách tiếp cận này thuận lợi nếu chúng ta thường thực hiện nhiều phép nối cho cùng một truy vấn. Không chuẩn hóa là phổ biến trong cơ sở dữ liệu SQL. Ví dụ: chúng ta có thể tạo một bảng liền kề để lưu trữ dữ liệu đã tham gia của mình trong cơ sở dữ liệu SQL

Không chuẩn hóa cũng tương tự trong MongoDB, với một điểm khác biệt đáng chú ý. Thay vì lưu trữ dữ liệu này dưới dạng một bảng phẳng, chúng ta có thể có các tài liệu lồng nhau biểu thị kết quả của tất cả các phép nối của chúng ta. Cách tiếp cận này tận dụng tính linh hoạt của các tài liệu phong phú của MongoDB. Và, chúng tôi có thể tự do lưu trữ dữ liệu theo bất kỳ cách nào phù hợp với ứng dụng của chúng tôi

Ví dụ: hãy tưởng tượng chúng ta có các bộ sưu tập MongoDB riêng biệt cho các sản phẩm, đơn đặt hàng và khách hàng. Tài liệu trong các bộ sưu tập này có thể trông như thế này

Sản phẩm

{
    "_id": 3,
    "name": "45' Yacht",
    "price": "250000",
    "description": "A luxurious oceangoing yacht."
}

khách hàng

{
    "_id": 47,
    "name": "John Q. Millionaire",
    "address": "1947 Mt. Olympus Dr.",
    "city": "Los Angeles",
    "state": "CA",
    "zip": "90046"
}

Gọi món

________số 8

Nếu chúng tôi không chuẩn hóa các tài liệu này để chúng tôi có thể truy xuất tất cả dữ liệu bằng một truy vấn, thì tài liệu đặt hàng của chúng tôi sẽ trông như thế này

{
    "_id": 49854,
    "product": {
        "name": "45' Yacht",
        "price": "250000",
        "description": "A luxurious oceangoing yacht."
    },
    "customer": {
        "name": "John Q. Millionaire",
        "address": "1947 Mt. Olympus Dr.",
        "city": "Los Angeles",
        "state": "CA",
        "zip": "90046"
    },
    "quantity": 3,
    "notes": "Three 45' Yachts for John Q. Millionaire. One for the east coast, one for the west coast, one for the Mediterranean".
}

Phương pháp này hoạt động trong thực tế vì trong quá trình ghi dữ liệu, chúng tôi lưu trữ tất cả dữ liệu chúng tôi cần trong tài liệu cấp cao nhất. Trong trường hợp này, chúng tôi đã hợp nhất dữ liệu sản phẩm và khách hàng vào tài liệu đặt hàng. Khi chúng tôi truy vấn thông tin ngay bây giờ, chúng tôi sẽ nhận được thông tin đó ngay lập tức. Chúng tôi không cần bất kỳ truy vấn cấp hai hoặc cấp ba nào để truy xuất dữ liệu của mình. Cách tiếp cận này làm tăng tốc độ và hiệu quả của các hoạt động đọc dữ liệu. Sự đánh đổi là nó yêu cầu xử lý trước bổ sung và tăng thời gian thực hiện cho mỗi thao tác ghi

Bản sao của sản phẩm và mọi người dùng mua sản phẩm đó đều là một thách thức bổ sung. Đối với một ứng dụng nhỏ, mức độ sao chép dữ liệu này không phải là vấn đề. Đối với ứng dụng thương mại điện tử giữa doanh nghiệp với doanh nghiệp, có hàng nghìn đơn đặt hàng cho mỗi khách hàng, việc sao chép dữ liệu này có thể nhanh chóng trở nên tốn kém về thời gian và dung lượng lưu trữ

Các tài liệu lồng nhau đó cũng không được liên kết theo quan hệ. Nếu có thay đổi đối với sản phẩm, chúng tôi cần tìm kiếm và cập nhật mọi phiên bản sản phẩm. Điều này có nghĩa là chúng tôi phải kiểm tra từng tài liệu trong bộ sưu tập vì chúng tôi sẽ không biết trước liệu thay đổi có ảnh hưởng đến nó hay không

Các lựa chọn thay thế để tham gia trong MongoDB

Cuối cùng, cơ sở dữ liệu SQL xử lý các phép nối tốt hơn MongoDB. Nếu chúng tôi thấy mình thường đạt tới

SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
0 hoặc một tập dữ liệu không chuẩn hóa, chúng tôi có thể tự hỏi liệu mình có đang sử dụng đúng công cụ cho công việc hay không. Có cách nào khác để tận dụng MongoDB cho ứng dụng của chúng tôi không?

Thay vì từ bỏ MongoDB hoàn toàn, chúng ta có thể tìm kiếm một giải pháp thay thế. Một khả năng là sử dụng giải pháp lập chỉ mục phụ đồng bộ hóa với MongoDB và được tối ưu hóa cho phân tích. Ví dụ: chúng tôi có thể sử dụng Rockset, cơ sở dữ liệu phân tích thời gian thực, để nhập trực tiếp từ các luồng thay đổi MongoDB, cho phép chúng tôi truy vấn dữ liệu của mình bằng các truy vấn tìm kiếm, tổng hợp và tham gia SQL quen thuộc

Sự kết luận

Chúng tôi có nhiều tùy chọn để tạo tập dữ liệu phong phú bằng cách kết hợp các yếu tố có liên quan từ nhiều bộ sưu tập. Phương thức đầu tiên là toán tử

SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
0. Công cụ đáng tin cậy này cho phép chúng tôi thực hiện tương đương với phép nối trái trên dữ liệu MongoDB của mình. Hoặc, chúng tôi có thể chuẩn bị một bộ sưu tập không chuẩn hóa cho phép truy xuất nhanh các truy vấn mà chúng tôi yêu cầu. Thay thế cho các tùy chọn này, chúng tôi có thể sử dụng các khả năng phân tích SQL của Rockset trên dữ liệu trong MongoDB, bất kể cấu trúc của nó như thế nào

Nếu bạn chưa thử khả năng phân tích thời gian thực của Rockset, tại sao bạn không thử?


Rockset là cơ sở dữ liệu phân tích thời gian thực trên đám mây dành cho các nhóm dữ liệu hiện đại. Nhận phân tích nhanh hơn trên dữ liệu mới hơn, với chi phí thấp hơn, bằng cách khai thác lập chỉ mục qua quá trình quét mạnh mẽ

Làm cách nào bạn có thể triển khai 1 đến nhiều mối quan hệ trong MongoDB?

Trong MongoDB, quan hệ một-một, một-nhiều và nhiều-nhiều có thể được triển khai theo hai cách. Sử dụng tài liệu nhúng . Sử dụng tài liệu tham khảo của bộ sưu tập khác.

$lookup trong MongoDB là gì?

Toán tử $lookup là toán tử tổng hợp hoặc giai đoạn tổng hợp, được sử dụng để nối tài liệu từ một tập hợp này với tài liệu của một tập hợp khác của cùng một cơ sở dữ liệu dựa trên một số . Cả hai bộ sưu tập phải thuộc cùng một cơ sở dữ liệu. . Both the collections should belong to the same databases.

MongoDB có thể tạo nhiều mô hình không

Mối quan hệ nhiều-nhiều (N. M) . Điều này cũng đúng khi sử dụng mongoDB để triển khai chúng. Trên thực tế, bạn không thể sử dụng lệnh để tạo bất kỳ loại mối quan hệ nào trong MongoDB .

Khi nào chúng ta nên xem xét đại diện cho một

Trong cơ sở dữ liệu quan hệ, tồn tại mối quan hệ một-nhiều khi một hàng trong bảng A có thể được liên kết với nhiều hàng trong bảng B, nhưng một hàng trong bảng B là . Điều quan trọng cần lưu ý là mối quan hệ một-nhiều không phải là thuộc tính của dữ liệu, mà là của chính mối quan hệ đó. . It is important to note that a one-to-many relationship is not a property of the data, but rather of the relationship itself.