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

Nhóm tài liệu trong MongoDB với điều kiện đặc biệt

Tuyên bố từ chối trách nhiệm

Trước khi đọc phần còn lại của câu trả lời, vui lòng đọc https:// docs. mongodb.com/manual/core/aggregation-pipeline-limits/ Tài liệu kết quả trong câu hỏi dự kiến ​​sẽ có một mảng gồm tất cả các tài liệu thuộc nhóm tuổi cụ thể. Kích thước của mảng đó không được vượt quá 16MB , do đó, mã bên dưới sẽ chỉ hoạt động cho các bộ sưu tập rất nhỏ các tài liệu nhỏ.

Mã:

db.collection.aggregate([
    { $sort: { age: 1 } },
    { $group: {
            _id: null,
            ages: { $push: "$age" }
    } },
    { $addFields: {
        ranges: { $reduce: { 
            input: { $range: [ 1, { $size: "$ages" }, 1 ] }, 
            initialValue: [ [ { $arrayElemAt: [ "$ages", 0 ] } ] ], 
            in: { $cond: { 
                if:  { $gt: [
                    { $subtract: [ { $arrayElemAt: [ "$ages", "$$this" ] }, { $arrayElemAt: [ "$ages", { $subtract: [ "$$this", 1 ] } ] } ] },
                    2
                    ] }, 
                then: { $concatArrays: [ "$$value",  [ [ { $arrayElemAt: [ "$ages", "$$this" ] } ] ] ] }, 
                else: { $concatArrays: [ 
                    { $slice: [ "$$value" , { $subtract: [ { $size: "$$value" }, 1 ] } ] },
                    [ { $concatArrays: [ 
                        { $arrayElemAt: [ { $slice: [ "$$value" , -1 ] }, 0 ] }  ,  
                        [ { $arrayElemAt: [ "$ages", "$$this" ] } ]
                    ]  } ]
                ] }
            } }
        } } 
    } },
    { $unwind: "$ranges" }, 
    { $lookup: {
       from: "collection",
       localField: "ranges",
       foreignField: "age",
       as: "group"
     } },
     { $project: { _id: 0, group: 1 } }
])

Phần có thể cần giải thích một chút là cách tính nhóm tuổi.

Đối với điều đó, chúng tôi nhận được mọi lứa tuổi bằng cách sử dụng $ group vào một mảng và sau đó $ addFields "phạm vi" - mảng 2D gồm các nhóm tuổi với khoảng cách giữa người cao tuổi nhất trong nhóm trẻ hơn và người trẻ nhất trong nhóm tuổi lớn hơn 2 tuổi.

Mảng được tính bằng cách sử dụng $ giảm của $ phạm vi mảng các chỉ mục thuộc mọi độ tuổi, trừ các chỉ số đầu tiên, chuyển sang giá trị ban đầu.

Biểu thức thu gọn là $ cond tính toán sự khác biệt giữa hiện tại và trước đó ( $ trừ ) phần tử của mảng ở mọi lứa tuổi.

Nếu lớn hơn 2, một nhóm tuổi mới sẽ được thêm vào bằng cách sử dụng $ concatArrays . Nếu không, độ tuổi sẽ được thêm vào nhóm già nhất bằng cách sử dụng $ slice để đẩy lên nhóm cuối cùng trong mảng phạm vi và $ setUnion để loại bỏ các bản sao.

Khi nhóm tuổi được tính toán, chúng tôi $ lookup cùng một bộ sưu tập theo độ tuổi để nhóm chúng trong mảng "nhóm".




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Nhận thông báo cho các tài liệu đã thay đổi trong mongodb

  2. MongoDB tổng hợp dự án chọn lọc

  3. Cách trừ hai ngày giờ trong mongodb

  4. Làm cách nào để xóa một cơ sở dữ liệu Mongo trống có cùng tên với một cơ sở dữ liệu đã nhập?

  5. Lọc bỏ các mảng trùng lặp và trả về mảng duy nhất trong tổng hợp mongodb