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

Cách nhóm theo các trường khác nhau

Đó là một khó khăn!

Đầu tiên, giải pháp đơn giản:

db.test.aggregate([
 { "$match": { "user": "Hans" } },
 // duplicate each document: one for "age", the other for "childs"
 { $project: { age: "$age", childs: "$childs",
               data: {$literal: ["age", "childs"]}}},
 { $unwind: "$data" },
 // pivot data to something like { data: "age", value: "40" }
 { $project: { data: "$data",
               value: {$cond: [{$eq: ["$data", "age"]},
                               "$age", 
                               "$childs"]} }},
 // Group by data type, and count
 { $group: { _id: {data: "$data", value: "$value" }, 
             count: { $sum: 1 }, 
             value: {$first: "$value"} }},
 // aggregate values in an array for each independant (type,value) pair
 { $group: { _id: "$_id.data", values: { $push: { count: "$count", value: "$value" }} }} ,
 // project value to the correctly name field
 { $project: { result: {$cond: [{$eq: ["$_id", "age"]},
                               {age: "$values" }, 
                               {childs: "$values"}]} }},
 // group all data in the result array, and remove unneeded `_id` field 
 { $group: { _id: null, result: { $push: "$result" }}},
 { $project: { _id: 0, result: 1}}
])

Sản xuất:

{
    "result" : [
        {
            "age" : [
                {
                    "count" : 3,
                    "value" : "40"
                },
                {
                    "count" : 1,
                    "value" : "50"
                }
            ]
        },
        {
            "childs" : [
                {
                    "count" : 1,
                    "value" : "1"
                },
                {
                    "count" : 3,
                    "value" : "2"
                }
            ]
        }
    ]
}

Và bây giờ, để có một số giải thích:

Một trong những vấn đề chính ở đây là mỗi tài liệu đến phải là một phần của hai các khoản tiền khác nhau. Tôi đã giải quyết điều đó bằng cách thêm một mảng chữ ["age", "childs"] vào tài liệu của bạn, rồi giải nén chúng theo mảng đó. Bằng cách đó, mỗi tài liệu sẽ được trình bày hai lần trong giai đoạn sau.

Sau khi hoàn tất, để dễ dàng xử lý, tôi thay đổi biểu diễn dữ liệu thành một thứ dễ quản lý hơn như { data: "age", value: "40" }

Các bước sau sẽ thực hiện tổng hợp dữ liệu theo từng lần. Lên đến $project thứ ba bước sẽ ánh xạ các trường giá trị với age tương ứng hoặc childs trường.

Hai bước cuối cùng sẽ chỉ gói gọn hai tài liệu thành một, xóa _id không cần thiết trường.

Pfff!




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Danh sách kiểm tra bảo mật cho việc triển khai sản xuất MongoDB

  2. Các Chức năng Đám mây của Google có kết nối lại với Ứng dụng khách MongoDB của tôi cho mỗi yêu cầu HTTP không?

  3. MongoDB - $ text operator tìm kiếm cho cụm từ HOẶC (các) từ

  4. Mongoose, mảng vị trí chỉ mục

  5. Làm thế nào để chuyển đổi mongo ObjectId .toString mà không bao gồm trình bao bọc 'ObjectId ()' - chỉ có Giá trị?