MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Cara mengelompokkan berdasarkan bidang yang berbeda

Itu sangat sulit!

Pertama, solusi sederhana:

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}}
])

Memproduksi:

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

Dan sekarang, untuk beberapa penjelasan:

Salah satu masalah utama di sini adalah bahwa setiap dokumen yang masuk harus menjadi bagian dari dua jumlah yang berbeda. Saya memecahkannya dengan menambahkan array literal ["age", "childs"] ke dokumen Anda, dan kemudian membukanya dengan larik itu. Dengan begitu, setiap dokumen akan ditampilkan dua kali pada tahap selanjutnya.

Setelah selesai, untuk memudahkan pemrosesan, saya mengubah representasi data menjadi sesuatu yang jauh lebih mudah dikelola seperti { data: "age", value: "40" }

Langkah-langkah berikut akan melakukan agregasi data per-se. Hingga $project ketiga langkah yang akan memetakan bidang nilai ke age yang sesuai atau childs lapangan.

Dua langkah terakhir hanya akan membungkus dua dokumen menjadi satu, menghapus _id . yang tidak diperlukan lapangan.

Pffff!




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Skema luwak:Memvalidasi bidang unik, tidak peka huruf besar-kecil

  2. Mengurai Keamanan Server

  3. Penggunaan collation di mongodb $regex

  4. Cara mengonfigurasi SELinux untuk Kumpulan Replika MongoDB

  5. Bisakah MongoDB menggunakan indeks saat memeriksa keberadaan bidang dengan operator $exists?