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

Batasi agregasi dalam agregasi berkelompok

Karena pertanyaan Anda saat ini tidak jelas, saya sangat berharap maksud Anda bahwa Anda ingin menentukan dua Site kunci dan 2 Software kunci karena itu adalah jawaban yang bagus dan sederhana yang dapat Anda tambahkan ke fase $match Anda seperti pada:

{$match: {
    group_id: "20ea74df4f7074b33b520000",
    tracked_item_name: {$in: ['Twitter', 'Facebook', 'Word', 'Excel' ] }
}},

Dan kita semua bisa bersorak dan bahagia;)

Namun jika pertanyaan Anda adalah sesuatu yang lebih jahat seperti, mendapatkan 2 Site teratas dan Software entri dari hasil dengan durasi, maka kami berterima kasih banyak untuk menelurkan kekejian . ini .

Peringatan:

Jarak tempuh Anda mungkin berbeda pada apa yang sebenarnya ingin Anda lakukan atau apakah ini akan meledak dengan ukuran hasil Anda. Tapi berikut ini sebagai contoh dari apa yang Anda inginkan:

db.collection.aggregate([

    // Match items first to reduce the set
    {$match: {group_id: "20ea74df4f7074b33b520000" }},

    // Group on the types and "sum" of duration
    {$group: {
        _id: {
            tracked_item_type: "$tracked_item_type",
            tracked_item_name: "$tracked_item_name"
         },
         duration: {$sum: "$duration"}
    }},

    // Sort by type and duration descending
    {$sort: { "_id.tracked_item_type": 1, duration: -1 }},

    /* The fun part */

    // Re-shape results to "sites" and "software" arrays 
    {$group: { 
        _id: null,
        sites: {$push:
            {$cond: [
                {$eq: ["$_id.tracked_item_type", "Site" ]},
                { _id: "$_id", duration: "$duration" },
                null
            ]}
        },
        software: {$push:
            {$cond: [
                {$eq: ["$_id.tracked_item_type", "Software" ]},
                { _id: "$_id", duration: "$duration" },
                null
            ]}
        }
    }},


    // Remove the null values for "software"
    {$unwind: "$software"},
    {$match: { software: {$ne: null} }},
    {$group: { 
        _id: "$_id",
        software: {$push: "$software"}, 
        sites: {$first: "$sites"} 
    }},

    // Remove the null values for "sites"
    {$unwind: "$sites"},
    {$match: { sites: {$ne: null} }},
    {$group: { 
        _id: "$_id",
        software: {$first: "$software"},
        sites: {$push: "$sites"} 
    }},


    // Project out software and limit to the *top* 2 results
    {$unwind: "$software"},
    {$project: { 
        _id: 0,
        _id: { _id: "$software._id", duration: "$software.duration" },
        sites: "$sites"
    }},
    {$limit : 2},


    // Project sites, grouping multiple software per key, requires a sort
    // then limit the *top* 2 results
    {$unwind: "$sites"},
    {$group: {
        _id: { _id: "$sites._id", duration: "$sites.duration" },
        software: {$push: "$_id" }
    }},
    {$sort: { "_id.duration": -1 }},
    {$limit: 2}

])  

Sekarang hasilnya adalah *tidak persis kumpulan hasil bersih yang ideal tetapi itu adalah sesuatu yang dapat dikerjakan secara terprogram, dan lebih baik daripada memfilter hasil sebelumnya dalam satu lingkaran. (Data saya dari pengujian)

{
    "result" : [
        {
            "_id" : {
                "_id" : {
                    "tracked_item_type" : "Site",
                    "tracked_item_name" : "Digital Blasphemy"
                 },
                 "duration" : 8000
            },
            "software" : [
                {
                    "_id" : {
                        "tracked_item_type" : "Software",
                        "tracked_item_name" : "Word"
                    },
                    "duration" : 9540
                },

                {
                    "_id" : {
                        "tracked_item_type" : "Software",
                        "tracked_item_name" : "Notepad"
                    },
                    "duration" : 4000
                }
            ]
        },
        {
            "_id" : {
                "_id" : {
                    "tracked_item_type" : "Site",
                    "tracked_item_name" : "Facebook"
                 },
                 "duration" : 7920
            },
            "software" : [
                {
                    "_id" : {
                        "tracked_item_type" : "Software",
                         "tracked_item_name" : "Word"
                    },
                    "duration" : 9540
                },
                {
                    "_id" : {
                        "tracked_item_type" : "Software",
                        "tracked_item_name" : "Notepad"
                    },
                    "duration" : 4000
                }
            ]
        }
    ],
    "ok" : 1
}

Jadi Anda melihat Anda mendapatkan 2 Site teratas dalam larik, dengan 2 Software teratas item tertanam di masing-masing. Agregasi itu sendiri, tidak dapat menjelaskan lebih jauh, karena kita perlu menggabungkan kembali item yang kami pisahkan untuk melakukan ini, dan belum ada operator yang dapat kami gunakan untuk melakukan tindakan ini.

Tapi itu menyenangkan. Bukan semua cara dilakukan, tetapi sebagian besar cara, dan menjadikannya sebagai respons 4 dokumen akan menjadi kode yang relatif sepele. Tapi kepalaku sudah sakit.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. mendapatkan InvalidOperationException saat menanyakan dengan AsQueryable di C #

  2. Paksa mongodb untuk mengeluarkan JSON yang ketat

  3. Mengonversi tanggal yang disimpan mongo kembali menjadi milidetik sejak zaman Unix saat dimuat?

  4. MongoDB - Perbarui bidang dalam objek array berdasarkan nilai bidang array bersarang

  5. Cara Mengimpor format file .bson di mongodb