Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MongoDB

Thực hiện $lookup với mảng ObjectId trong MongoDB

Toán tử $lookup thực hiện left outer join với collection khác. Khi trường khóa ngoại là **mảng ObjectId**, dùng pipeline con với $match và $in.

Tạo collection chính (demo395):

> db.demo395.insertOne({Name:"Chris"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5e782317aa3ef9ab8ab207") }
> db.demo395.insertOne({Name:"David"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5e782317aa3ef9ab8ab208") }

Tạo collection tham chiếu (demo396) chứa mảng ObjectId:

> db.demo396.insertOne({
  "details" : [
    ObjectId("5e5e782317aa3ef9ab8ab207"),
    ObjectId("5e5e782317aa3ef9ab8ab208")
  ]
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5e787817aa3ef9ab8ab209") }

Xem dữ liệu:

> db.demo395.find();
> db.demo396.find();

$lookup với pipeline để join mảng ObjectId:

> db.demo396.aggregate([
  { "$lookup": {
    "from": "demo395",
    "let": { "details": "$details" },
    "pipeline": [
      { "$match": { "$expr": { "$in": [ "$_id", "$$details" ] } } }
    ],
    "as": "output"
  }}
])

Kết quả (có mảng output chứa tài liệu join được):

Giải thích:

  • let: định nghĩa biến details từ trường mảng ObjectId
  • pipeline: pipeline con chạy trên collection from
  • $match + $expr + $in: lọc tài liệu có _id nằm trong mảng $$details
  • as: tên trường chứa kết quả join (mảng)

Cách này linh hoạt hơn $lookup đơn giản (localField/foreignField) khi khóa ngoại là mảng.