MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Aggregate $ lookup không trả về thứ tự mảng ban đầu của các phần tử

Đây là "theo thiết kế" của $lookup thực hiện. Thực ra là gì xảy ra "under the hood" là MongoDB internall chuyển đổi các đối số trong $lookup sang biểu cảm mới định dạng bằng $expr$in . Ngay cả trong các phiên bản trước khi biểu cảm này đã được triển khai, cơ chế nội bộ cho "mảng giá trị" thực sự rất giống nhau.

Giải pháp ở đây là duy trì một bản sao của mảng ban đầu làm tham chiếu để sắp xếp lại thứ tự "đã tham gia" mặt hàng:

collection.aggregate([
  {"$match": {"_id": ObjectId("5c781752176c512f180048e3") }},
  {"$lookup": {
    "from": "collection2",
    "let": { "classIds": "$Classes.ID" },
    "pipeline": [
      { "$match": {
        "$expr": { "$in": [ "$_id", "$$classIds" ] }
      }},
      { "$addFields": {
        "sort": {
          "$indexOfArray": [ "$$classIds", "$_id" ]
        }
      }},
      { "$sort": { "sort": 1 } },
      { "$addFields": { "sort": "$$REMOVE" }}
    ],
    "as": "results"
  }}
])

Hoặc bằng $lookup kế thừa cách sử dụng:

collection.aggregate([
  {"$match": {"_id": ObjectId("5c781752176c512f180048e3") }},
  {"$lookup": {
    "from": "collection2",
    "localField": "Classes.ID",
    "foreignField": "_id",
    "as": "results"
  }},
  { "$unwind": "$results" },
  { "$addFields": {
    "sort": {
      "$indexOfArray": [ "$Classes.ID", "$results._id" ]
    }
  }},
  { "$sort": { "_id": 1, "sort": 1 } },
  { "$group": {
    "_id": "$_id",
    "Name": { "$first": "$Name" },
    "Classes": { "$first": "$Classes" },
    "results": { "$push": "$results" }
  }}
])

Cả hai biến thể đều tạo ra cùng một đầu ra:

{
        "_id" : ObjectId("5c781752176c512f180048e3"),
        "Name" : "Pedro",
        "Classes" : [
                {
                        "ID" : ObjectId("5c7af2b2f6f6e47c9060d7ce")
                },
                {
                        "ID" : ObjectId("5c7af2bcf6f6e47c9060d7cf")
                },
                {
                        "ID" : ObjectId("5c7af2aaf6f6e47c9060d7cd")
                }
        ],
        "results" : [
                {
                        "_id" : ObjectId("5c7af2b2f6f6e47c9060d7ce"),
                        "variable1" : "B"
                },
                {
                        "_id" : ObjectId("5c7af2bcf6f6e47c9060d7cf"),
                        "variable1" : "C"
                },
                {
                        "_id" : ObjectId("5c7af2aaf6f6e47c9060d7cd"),
                        "variable1" : "A"
                }
        ]
}

Khái niệm chung là sử dụng $indexOfArray so với _id giá trị từ "đã tham gia" nội dung cần tìm là "chỉ mục" vị trí trong mảng nguồn ban đầu từ "$Classes.ID" . $lookup khác nhau các biến thể cú pháp có các cách tiếp cận khác nhau đối với cách bạn truy cập vào bản sao này và cách bạn xây dựng lại về cơ bản.

$sort tất nhiên đặt thứ tự của các tài liệu thực tế, hoặc đang được bên trong xử lý đường ống cho biểu mẫu biểu cảm hoặc thông qua các tài liệu tiếp xúc của $unwind . Nơi bạn đã sử dụng $unwind sau đó bạn sẽ $group trở lại biểu mẫu tài liệu ban đầu.

LƯU Ý :Các ví dụ sử dụng ở đây phụ thuộc vào MongoDB 3.4 cho $indexOfArray ít nhất và $$REMOVE căn chỉnh với MongoDB 3.6 giống như biểu cảm $lookup .

Có các cách tiếp cận khác để sắp xếp lại mảng cho các bản phát hành trước, nhưng những cách này được thể hiện chi tiết hơn về thứ tự đảm bảo điều khoản $ in của MongoDB. Thực tế, mức tối thiểu mà bạn hiện có thể chạy dưới dạng phiên bản MongoDB sản xuất là bản phát hành 3.4.

Xem Chính sách hỗ trợ trong Máy chủ MongoDB để biết chi tiết đầy đủ về các bản phát hành được hỗ trợ và ngày kết thúc.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Khung tổng hợp Mongodb | Nhóm trên nhiều giá trị?

  2. Chỉ truy xuất phần tử được truy vấn trong một mảng đối tượng trong bộ sưu tập MongoDB

  3. Kiến trúc để bảo mật:Hướng dẫn cho MongoDB

  4. Hiện có sẵn:Phiên bản MongoDB được lưu trữ đầy đủ trên AWS

  5. Kiểm thử đơn vị với MongoDB