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

Khớp tập giao (intersection) tài liệu theo trường trong MongoDB Aggregation

Sử dụng aggregation pipeline với $group và $match lồng $all + $elemMatch để tìm nhóm tài liệu chia sẻ cùng một giá trị trường VÀ chứa tất cả các giá trị chỉ định của trường khác.

Tạo collection:

> db.demo393.insertOne({Id1:"1", Name:"Chris", Id2:"100"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5e6dd522064be7ab44e804") }
> db.demo393.insertOne({Id1:"1", Name:"Chris", Id2:"101"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5e6dd522064be7ab44e805") }
> db.demo393.insertOne({Id1:"3", Name:"Chris", Id2:"100"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5e6dd522064be7ab44e806") }
> db.demo393.insertOne({Id1:"3", Name:"Mike", Id2:"101"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5e6dd522064be7ab44e807") }

Xem dữ liệu:

> db.demo393.find();

Aggregation: nhóm theo Id1, chỉ giữ nhóm có Name="Chris" VÀ chứa CẢ HAI Id2="100" VÀ Id2="101":

> db.demo393.aggregate([
  { "$match": { "Name": "Chris" } },
  { "$group": {
    "_id": "$Id1",
    "docs": { "$push": "$$ROOT" },
    "count": { "$sum": 1 }
  }},
  { "$match": {
    "count": { "$gt": 1 },
    "docs": {
      "$all": [
        { "$elemMatch": { "Id2": "100" } },
        { "$elemMatch": { "Id2": "101" } }
      ]
    }
  }}
])

Kết quả (chỉ nhóm Id1="1" thỏa mãn):

Phân tích logic:

  1. $match Name="Chris": lọc trước
  2. $group by Id1: gom tài liệu, đẩy toàn bộ doc vào mảng docs, đếm count
  3. $match thứ 2: lọc nhóm có count>1 VÀ mảng docs chứa **tất cả** các phần tử khớp 2 điều kiện Id2=100 và Id2=101 (qua $all + $elemMatch)

Kỹ thuật này tìm "giao nhau" các tập tài liệu theo nhiều tiêu chí.