Mảng trường cục bộ tra cứu mongodb

MongoDB cung cấp $lookup để tham gia bộ sưu tập với các bộ sưu tập khác. Ví dụ: giả sử khách hàng có danh sách đơn đặt hàng và chúng tôi muốn biết ánh xạ bộ sưu tập của khách hàng tới sản phẩm mà khách hàng đã đặt hàng

Hãy lấy một bộ sưu tập khách hàng

Ở đây chúng tôi có các đơn đặt hàng với id của bộ sưu tập đơn hàng và chúng tôi sẽ ánh xạ khóa đơn hàng tới bộ sưu tập đơn hàng

db.customers.insert([
  { "_id": 1, "name": "Jason", "orders": [1,2] },
  { "_id": 2, "name": "Drake", "orders": [2,3] },
  { "_id": 3, "name": "John", "orders":[1] }
])

Bây giờ chúng ta hãy lấy một bộ sưu tập đơn đặt hàng

db.orders.insert([
  { "_id": 1, "productName": "Ipad", "price": 20 },
  { "_id": 2, "productName": "Laptop", "price": 10 },
  { "_id": 3, "productName": "Computer Accessories", "price":40 }
])

Bây giờ chúng tôi sử dụng $lookup để tham gia các bộ sưu tập trên. Hãy xem trong hành động

db.customers.aggregate([
  {
    $project: {
      _id: 1,
      name: 1,
      orders: 1
    }
  },
  {
    $lookup: {
      from: "orders",
      localField: "orders",
      foreignField: "_id",
      as: "orders"
    }
  }
])

Bấm chạy để xem kết quả

Như bạn có thể thấy ở trên cách các đơn đặt hàng từ bộ sưu tập khách hàng được ánh xạ tới bộ sưu tập đơn đặt hàng bằng cách sử dụng _id

_id chúng tôi có trong mảng đơn đặt hàng của khách hàng là _id tùy chỉnh không phải là Id được tạo tự động duy nhất của mongodb

Điều gì sẽ xảy ra nếu họ có mảng Id được tạo tự động. Hãy xem một ví dụ

db.customers.insert(
[
    {
      "_id": 1,
      "name": "Jason",
      "orders": [
        "5e671cc4a5c7ed3fa4e2226a",
        "5f5cf89f05f4a755e8570378"
      ]
    },
    {
      "_id": 2,
      "name": "Drake",
      "orders": [
        "5dd4ec16661c583dd88815e5",
        "5e671cc4a5c7ed3fa4e2226a"
      ]
    },
    {
      "_id": 3,
      "name": "John",
      "orders": [
        "5dd4ec16661c583dd88815e5"
      ]
    }
  ]
)

Thu thập đơn đặt hàng với Id đối tượng được tạo tự động

db.orders.insert(
[
    {
      "_id": ObjectId("5e671cc4a5c7ed3fa4e2226a"),
      "productName": "Ipad",
      "price": 20
    },
    {
      "_id": ObjectId("5f5cf89f05f4a755e8570378"),
      "productName": "Laptop",
      "price": 10
    },
    {
      "_id": ObjectId("5dd4ec16661c583dd88815e5"),
      "productName": "Computer Accessories",
      "price": 40
    }
  ]
)

Sử dụng tra cứu $ ngay bây giờ để kiểm tra xem nó có hoạt động không

db.customers.aggregate([
  {
    $project: {
      _id: 1,
      name: 1,
      orders: 1
    }
  },
  {
    $lookup: {
      from: "orders",
      localField: "orders",
      foreignField: "_id",
      as: "orders"
    }
  }
])

Như bạn có thể thấy nó không hoạt động vì bộ sưu tập đơn đặt hàng của chúng tôi có _id là ObjectId và bộ sưu tập khách hàng có mảng id chuỗi nhưng không phải là ObjectId

điểm. 1

câu trả lời được chấp nhận

Bạn co thể thử ,

  • $lookup tham gia thu gom hàng tồn kho
  • $match để khớp là khoảng không quảng cáo sku trong mảng item
  • $project để hiển thị các trường bắt buộc
db.orders.aggregate([
  {
    $lookup: {
      from: "inventory",
      as: "item",
      let: { i: "$item" },
      pipeline: [
        { $match: { $expr: { $in: ["$sku", "$$i"] } } },
        {
          $project: {
            _id: 0,
            sku: 1,
            instock: 1
          }
        }
      ]
    }
  }
])

Sân chơi

Thêm câu hỏi với thẻ tương tự


lời nói đầu. Bạn mới sử dụng quy trình tổng hợp?

Ngoài ra, hãy chắc chắn hiểu lập chỉ mục và ý nghĩa hiệu suất của nó trước khi xem xét các ví dụ này

$lookup cho phép bạn thực hiện phép nối trên các bộ sưu tập trong cùng một cơ sở dữ liệu. $lookup hoạt động bằng cách trả về tài liệu từ bộ sưu tập "đã tham gia" dưới dạng mảng con của bộ sưu tập gốc

$lookup hỗ trợ cả các đối sánh đẳng thức cơ bản cũng như các truy vấn phụ không tương quan. Chúng tôi sẽ cung cấp một ví dụ về từng kịch bản

Các ví dụ dựa trên dữ liệu mẫu này

thu bài

{
    "title" : "my first post",
    "author" : "Jim",
    "likes" : 5
},
{
    "title" : "my second post",
    "author" : "Jim",
    "likes" : 2
},
{
    "title" : "hello world",
    "author" : "Joe",
    "likes" : 3
}

bộ sưu tập bình luận

________số 8_______

Lưu ý cách chúng tôi có hai bộ sưu tập bài đăng và bình luận. Trường postTitle trong bộ sưu tập nhận xét tương ứng với trường tiêu đề trong bộ sưu tập bài viết

Cả bình luận và bài đăng đều có lượt thích

ví dụ tra cứu $. trận đấu bình đẳng

db.posts.aggregate([
    { $lookup:
        {
           from: "comments",
           localField: "title",
           foreignField: "postTitle",
           as: "comments"
        }
    }
])

Lưu ý cách $lookup lấy một tài liệu với các trường sau

  • từ. bộ sưu tập chúng tôi muốn tham gia cùng
  • trường địa phương. trường chúng tôi muốn tham gia trong bộ sưu tập cục bộ (bộ sưu tập chúng tôi đang chạy truy vấn)
  • vùng ngoại quốc. lĩnh vực chúng tôi muốn tham gia trong bộ sưu tập nước ngoài (bộ sưu tập chúng tôi muốn tham gia)
  • như. tên của mảng đầu ra cho kết quả

Truy vấn này trả về như sau

{
    "title" : "my first post",
    "author" : "Jim",
    "likes" : 5,
    "comments" : [
        {
            "postTitle" : "my first post",
            "comment" : "great read",
            "likes" : 3
        }
    ]
},
{
    "title" : "my second post",
    "author" : "Jim",
    "likes" : 2,
    "comments" : [
        {
            "postTitle" : "my second post",
            "comment" : "good info",
            "likes" : 0
        },
        {
            "postTitle" : "my second post",
            "comment" : "i liked this post",
            "likes" : 12
        }
    ]
},
{
    "title" : "hello world",
    "author" : "Joe",
    "likes" : 3,
    "comments" : [
        {
            "postTitle" : "hello world",
            "comment" : "not my favorite",
            "likes" : 8
        }
    ]
}

Lưu ý cách 3 tài liệu gốc từ bộ sưu tập bài đăng được trả lại với một trường bổ sung nhận xét

Đối với mỗi bài đăng, mảng nhận xét mới này có tất cả các tài liệu từ bộ sưu tập nhận xét có trường postTitle khớp với trường tiêu đề của bài đăng

ví dụ tra cứu $. ví dụ đường ống với điều kiện

db.posts.aggregate([
 { $lookup:
     {
       from: "comments",
       let: { post_likes: "$likes", post_title: "$title"},
       pipeline: [
            { $match:
                { $expr:
                    { $and:
                        [
                           { $gt: [ "$likes", "$$post_likes"] },
                           { $eq: ["$$post_title", "$postTitle" ] }
                        ]
                    }
                }
            }
        ],
        as: "comments"
        }
 }
])

Lưu ý cách $lookup lấy các trường hơi khác nhau. Cụ thể, các trường localField và ForeignField đã được thay thế bằng

  • để (tùy chọn). một biểu thức xác định các biến để sử dụng trong giai đoạn đường ống. Đây là cách bạn truy cập các trường từ bộ sưu tập đầu vào trong giai đoạn quy trình
  • đường ống. một đường dẫn tổng hợp để thực hiện trên bộ sưu tập để tham gia

Chú ý cách chúng ta định nghĩa hai biến trong biểu thức let. Chúng tôi xác định post_likes và post_title để chúng tôi có thể tham chiếu các tài liệu đầu vào trong giai đoạn quy trình

Đây là cách duy nhất để chúng tôi so sánh giữa các bộ sưu tập khác nhau

{ $gt: [ "$likes", "$$post_likes"] },
{ $eq: ["$$post_title", "$postTitle" ] }

Lưu ý cách chúng ta sử dụng $$ để chỉ các biến mà chúng ta đã xác định trong let. Chúng tôi tham chiếu các trường trong bộ sưu tập nước ngoài với một $

Truy vấn này trả về như sau

{
    "title" : "my first post",
    "author" : "Jim",
    "likes" : 5,
    "comments" : []
},
{
    "title" : "my second post",
    "author" : "Jim",
    "likes" : 2,
    "comments" : [
        {
            "postTitle" : "my second post",
            "comment" : "i liked this post",
            "likes" : 12
        }
    ]
},
{
    "title" : "hello world",
    "author" : "Joe",
    "likes" : 3,
    "comments" : [
        {
            "postTitle" : "hello world",
            "comment" : "not my favorite",
            "likes" : 8
        }
    ]
}

Giống như ví dụ đầu tiên, truy vấn này trả về các nhận xét có postTitle khớp với trường tiêu đề cho mỗi bài đăng. Truy vấn này thêm một điều kiện bổ sung để trả lại nhận xét có số lượt thích lớn hơn số lượt thích của bài đăng tương ứng

Bằng cách chạy truy vấn này, giờ đây chúng tôi biết liệu có bài đăng nào có nhận xét với nhiều lượt thích hơn chính bài đăng đó không. )

Phần kết luận

Bây giờ bạn đã thấy hai ví dụ về việc sử dụng $lookup trong quy trình tổng hợp. Hãy nhớ rằng $lookup có thể được sử dụng cho cả kiểm tra đẳng thức (ví dụ đầu tiên) cũng như các truy vấn phụ phức tạp hơn (ví dụ thứ hai)

Tùy thuộc vào loại truy vấn bạn chạy, $lookup sẽ nhận các tham số hơi khác nhau (let, đường dẫn so với localField, ForeignField)

Để biết thêm về quy trình tổng hợp, hãy nhớ xem hướng dẫn dài 5 phút này về khung tổng hợp MongoDB

Suy nghĩ của bạn?

Chia sẻ những suy nghĩ của bạn

0

JavaDung Nham. Ngày 3 tháng 3 năm 2021

Mặc dù thật tốt khi $lookup tồn tại trong MongoDb, nhưng điều đó đi ngược lại mọi lý do khiến bạn sử dụng MongoDB so với kho dữ liệu quan hệ khác (MySQL).

Hãy nhớ rằng thao tác $lookup đi kèm với chi phí thực hiện thao tác THAM GIA trên bộ sưu tập của bạn. Hãy nhớ rằng một trong những ưu điểm chính của MongoDb là hiệu suất nhanh hơn với dữ liệu phi cấu trúc. sự trớ trêu.

Để minh họa thêm, giả sử bạn thiết lập một blog bằng Mongo. Một blog điển hình đi kèm với Người dùng, Bài đăng, Nhận xét, Lượt thích, Người theo dõi, v.v. Đây là rất nhiều MỐI QUAN HỆ để quản lý. Nếu bạn sử dụng MongoDb cho trường hợp sử dụng này, bạn có thể nhanh chóng gặp rắc rối (đặc biệt nếu mỗi thực thể được đại diện bởi tập hợp riêng của nó. )

Giả sử bạn muốn hiển thị bài đăng trên blog được người dùng thích nhất. Điều này sẽ yêu cầu một tập hợp UGLY Mongo nơi bạn tổng hợp các lượt thích, bình luận, v.v. cho một bài đăng nhất định. Đó là rất nhiều $tra cứu. và bắt đầu đặt câu hỏi "TẠI SAO KHÔNG CHỈ SỬ DỤNG SQL"

Tóm lại. tự hỏi bản thân xem bạn có đưa ra quyết định đúng đắn về kiến ​​trúc hay không khi thấy mình thường xuyên sử dụng $lookup .

0

Ngăn xếpTrưởngOG. Ngày 3 tháng 3 năm 2021

HÃY CẨN THẬN VỚI $lookup

Tại sao? . Hãy nhớ rằng MongoDb là kho lưu trữ dữ liệu phi quan hệ. Điều này có nghĩa là nó vượt trội với lượng lớn dữ liệu phi cấu trúc cần tra cứu nhanh

Khi bạn sử dụng $lookup , bạn đang thực hiện phép nối trên hai bộ sưu tập khác nhau. Đây là dữ liệu CÓ CẤU TRÚC. Nếu bạn thiết kế toàn bộ lược đồ xung quanh kho lưu trữ dữ liệu "không có lược đồ" thì bạn sẽ không được trả tiền để làm những gì bạn làm. )

Các kho lưu trữ dữ liệu quan hệ vẫn có vị trí của chúng. Mặc dù có rất nhiều sự cường điệu xung quanh NoSQL, iOT và đám mây (từ buzz), nhưng MySQL cũ và RDBMS khác vẫn được sử dụng rộng rãi trong sản xuất. và ở QUY MÔ

Làm cách nào để tìm giá trị trong mảng trong MongoDB?

Để truy vấn xem trường mảng có chứa ít nhất một phần tử có giá trị được chỉ định hay không, hãy sử dụng bộ lọc { . Để chỉ định điều kiện cho các phần tử trong trường mảng, hãy sử dụng các toán tử truy vấn trong tài liệu bộ lọc truy vấn. {

Làm cách nào để sử dụng đối sánh với tra cứu trong MongoDB?

$lookup thực hiện so khớp bình đẳng trên ForeignField với localField từ các tài liệu đầu vào . Nếu một tài liệu trong bộ sưu tập from không chứa ForeignField , thì $lookup coi giá trị là null cho các mục đích phù hợp. Chỉ định tên của trường mảng mới để thêm vào tài liệu đầu vào.

Làm cách nào để tìm nạp dữ liệu từ một bộ sưu tập khác trong MongoDB?

Để thực hiện MongoDB Tham gia hai bộ sưu tập, bạn phải sử dụng toán tử tra cứu $ . Nó được định nghĩa là một giai đoạn thực hiện nối ngoài bên trái với một bộ sưu tập khác và hỗ trợ lọc dữ liệu từ các tài liệu đã nối. Ví dụ: nếu người dùng yêu cầu tất cả các điểm từ tất cả học sinh, thì truy vấn bên dưới có thể được viết. Sinh viên.