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

$sum dari grup dokumen dan subdocuments oleh $author (MongoDB)

Tidak segera terlihat tetapi mungkin. Yang perlu Anda lakukan di sini adalah menggabungkan dokumen tingkat atas Anda dengan deretan komentar tanpa menduplikasinya. Berikut adalah pendekatan untuk menggabungkan konten terlebih dahulu sebagai dua larik ke dalam larik tunggal, lalu $unwind untuk mengelompokkan konten:

db.collection.aggregate([
    { "$group": {
        "_id": "$_id",
        "author": { 
            "$addToSet": {
                "id": "$_id",
                "author": "$author",
                "votes": "$votes"
            }
        },
        "comments": { "$first": "$comments" }
    }},
    { "$project": {
        "combined": { "$setUnion": [ "$author", "$comments" ] }
    }},
    { "$unwind": "$combined" },
    { "$group": {
        "_id": "$combined.author",
        "votes": { "$sum": "$combined.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

Yang memberikan output:

{ "_id" : "Jesse", "votes" : 148 }
{ "_id" : "Mirek", "votes" : 135 }
{ "_id" : "Leszke", "votes" : 13 }

Bahkan saat melewatkan $group stage dan membuat array gabungan dengan cara yang berbeda:

db.collection.aggregate([
    { "$project": {
        "combined": { 
            "$setUnion": [
                { "$map": {
                    "input": { "$literal": ["A"] },
                    "as": "el",
                    "in": { 
                        "author": "$author",
                        "votes": "$votes"
                    }
                }},
                "$comments"
            ] 
        }
    }},
    { "$unwind": "$combined" },
    { "$group": {
        "_id": "$combined.author",
        "votes": { "$sum": "$combined.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

Mereka menggunakan operator seperti $setUnion dan bahkan $map yang diperkenalkan pada MongoDB 2.6. Ini membuatnya lebih sederhana, tetapi masih dapat dilakukan di versi sebelumnya yang tidak memiliki operator tersebut, dengan mengikuti prinsip yang hampir sama:

db.collection.aggregate([
    { "$project": {
        "author": 1,
        "votes": 1,
        "comments": 1,
        "type": { "$const": ["A","B"] }
    }},
    { "$unwind": "$type" },
    { "$unwind": "$comments" },
    { "$group": { 
        "_id": {
          "$cond": [
              { "$eq": [ "$type", "A" ] },
              { 
                  "id": "$_id", 
                  "author": "$author",
                  "votes": "$votes"
              },
              "$comments"
          ]
        }
    }},
    { "$group": {
        "_id": "$_id.author",
        "votes": { "$sum": "$_id.votes" }
    }},
    { "$sort": { "votes": -1 } }
])

$const tidak didokumentasikan tetapi ada di semua versi MongoDB di mana kerangka kerja agregasi hadir (dari 2.2). MongoDB 2.6 Memperkenalkan $literal yang pada dasarnya menautkan ke kode dasar yang sama. Telah digunakan dalam dua kasus di sini untuk menyediakan elemen template untuk larik, atau sebagai memperkenalkan larik untuk bersantai guna memberikan "pilihan biner" di antara dua tindakan.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB, perbarui bidang koleksi jika nilai baru bukan nol

  2. Ulangi semua database Mongo

  3. Cara mencari di indeks fulltext menggunakan php di mongodb

  4. Bagaimana cara mengindeks array MongoDB?

  5. Apakah findOne luwak pada model mengembalikan janji?