Làm cách nào để tham gia hai tài liệu trong mongodb?

MongoDB không phải là cơ sở dữ liệu quan hệ, nhưng bạn có thể thực hiện phép nối ngoài bên trái bằng cách sử dụng giai đoạn

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

Giai đoạn

SELECT *, products
FROM users
WHERE products in (
  SELECT *
  FROM products
  WHERE id = users.product_id
);
0 cho phép bạn chỉ định bộ sưu tập nào bạn muốn tham gia với bộ sưu tập hiện tại và trường nào sẽ khớp

Giả sử bạn có bộ sưu tập "đơn đặt hàng" và bộ sưu tập "sản phẩm"

mệnh lệnh

[
  { _id. 1, product_id. 154, trạng thái. 1 }
]

Mỹ phẩm

[
  { _id. 154, tên. 'Thiên đường sô cô la' },
  { _id. 155, tên. 'Chanh ngon' },
  { _id. 156, tên. 'Giấc mơ vani' }
]

Thí dụ

Tham gia (các) tài liệu "sản phẩm" phù hợp với bộ sưu tập "đơn đặt hàng"

var MongoClient = require('mongodb'). MongoClient;
var url = "mongodb. //127. 0. 0. 1. 27017/";

MongoClient. connect(url, function(err, db) {
  if (err) throw err;
  var dbo = db. db("mydb");
  dbo. bộ sưu tập ('đơn đặt hàng'). tổng hợp([
    { $lookup.
       {
         từ. 'sản phẩm',
         localField. 'product_id',
         trường nước ngoài. '_id',
         như. 'chi tiết đơn hàng'
       }
     }
    ]). toArray(function(err, res) {
    if (err) throw err;
    bảng điều khiển. nhật ký (JSON. stringify(res));
    db. close();
  });
});

Chạy ví dụ »

Lưu mã ở trên vào tệp có tên "demo_mongodb_join. js" và chạy tệp

Chạy "demo_mongodb_join. js"

C. \Users\Tên của bạn>nút demo_mongodb_join. js

Cái nào sẽ cho bạn kết quả này

[
  { "_id". 1, "id_sản phẩm". 154, "trạng thái". 1, "chi tiết đơn hàng". [
    { "_id". 154, "tên". "Thiên đường sô cô la" } ]
  }
]

Như bạn có thể thấy từ kết quả ở trên, tài liệu phù hợp từ bộ sưu tập sản phẩm được bao gồm trong bộ sưu tập đơn đặt hàng dưới dạng một mảng

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 đợi. 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 điều 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 thực sự 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ẽ

Tại sao phép nối không được sử dụng trong MongoDB?

Kết luận là các kết nối MongoDB rất dễ vỡ (khi mọi thứ thay đổi, các chương trình ứng dụng phải được mã hóa lại nhiều lần) và MongoDB thường cung cấp hiệu suất rất kém, so với Postgres

Hợp nhất trong MongoDB là gì?

$merge chèn tài liệu trực tiếp vào bộ sưu tập đầu ra . Trước MongoDB 4. 2. 2, khi các điều kiện này cho giai đoạn $merge được đáp ứng, quy trình bán hàng được chỉ định trong trường whenMatched được thực thi với một tài liệu đầu vào trống. Tài liệu kết quả từ đường ống được chèn vào bộ sưu tập đầu ra.

Nhóm tài liệu được gọi trong MongoDB là gì?

MongoDB lưu trữ tài liệu trong bộ sưu tập. Bộ sưu tập tương tự như bảng trong cơ sở dữ liệu quan hệ

MongoDB quản lý mối quan hệ giữa các tài liệu như thế nào?

Trong MongoDB, một mối quan hệ thể hiện cách các loại tài liệu khác nhau có liên quan logic với nhau. Các mối quan hệ như một-một, một-nhiều, v.v. , có thể được biểu diễn bằng cách sử dụng hai mô hình khác nhau. Mô hình tài liệu nhúng .