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

mongodb:kueri beberapa baris pertama di mana jumlah kolom tertentu lebih besar atau sama dengan C

Kueri

Itu bisa dilakukan dengan menggunakan kerangka agregasi . Pertimbangkan pipa agregasi berikutnya

db.collectionName.aggregate([
  {
    $group: 
      { 
        "_id": null, 
        "ds": { $push: "$$ROOT" }, 
        "cs": { $push: "$c" } 
      } 
  }, /* (1) */
  { $unwind: "$ds" }, /* (2) */
  { 
    $project: 
      { 
        "_id": "$ds._id", 
        "c": "$ds.c", 
        "cs": { $slice: [ "$cs", "$ds._id" ] } 
      } 
  }, /* (3):  */
  { $unwind: "$cs" },  /* (4) */
  { 
    $group: 
      { 
        "_id": "$_id", 
        "c": { $first: "$c" }, 
        "csum": { $sum: "$cs" } 
      } 
  }, /* (5) */
  { 
    $group: 
      { 
        "_id": null, 
        "ds": { $push: "$$ROOT" }, 
        "gteC": 
          { 
            $push: 
              { 
                $cond: 
                  { 
                    if: { "$gte": [ "$csum", SET_DESIRED_VALUE_FOR_C_HERE ] }, 
                    then: "$$ROOT", 
                    else: { } 
                  } 
              } 

          } 
      } 
  }, /* (6) */
  { 
    $project: 
      { 
        "_id": 0,
        "docs": 
          { 
            $filter: 
              { 
                input: "$ds", 
                "as": "doc", 
                cond: { $lte: [ "$$doc.csum", { $min: "$gteC.csum" } ] }
              }
          }
      }
  }, /* (7) */
  { $unwind: "$docs" }, /* (8) */ 
  { $project: { "_id": "$docs._id", "c": "$docs.c" } } /* (9) */
]);

Hasil

Penjelasan

Ide dasar di baliknya adalah untuk membangun array pembantu untuk setiap dokumen dalam koleksi (tahap 1-3 )

{ "_id" : 1, "c" : 2 } -> cs = [ 2 ]
{ "_id" : 2, "c" : 6 } -> cs = [ 2, 6 ]
{ "_id" : 3, "c" : 1 } -> cs = [ 2, 6, 1 ]

menggunakan $slice operator agregasi array lalu ganti dengan jumlah semua elemen yang dikandungnya (tahap 4-5 )

{ "_id" : 1, "c" : 2 } -> csum = 2
{ "_id" : 2, "c" : 6 } -> csum = 8
{ "_id" : 3, "c" : 1 } -> csum = 9

menggunakan $unwind stage dan $sum operator akumulator grup .

Kemudian buat susunan dokumen pembantu lain dengan csum >= C (tahap 6 )

/* Ex. (C = 8) */
gteC = [ { "_id" : 3, "c" : 1, "csum" : 9 }, { "_id" : 2, "c" : 6, "csum" : 8 } ]

Langkah terakhir adalah mengambil semua dokumen dengan csum <= Min { gteC.csum } . Ini dilakukan menggunakan $filter operator agregasi array (tahap 7 ).

Namun, saya tidak yakin ini yang paling efisien pipa agregasi (akan berterima kasih atas saran peningkatan apa pun) untuk mencapai apa yang Anda inginkan.

PS Sebelum menguji kueri, jangan lupa untuk mengubah nama koleksi dan mengganti SET_DESIRED_VALUE_FOR_C_HERE.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Runtime mengubah model dengan mongodb/mongoid

  2. Luwak dengan boolean unik dari true

  3. MongoDB tersemat saat menjalankan tes integrasi

  4. Mongodb dan Express

  5. luwak berbeda dan diisi dengan dokumen