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

String Concat berdasarkan Grup

Anda dapat melakukannya dengan kerangka kerja agregasi sebagai operasi "dua langkah". Yang pertama mengumpulkan item ke array melalui $push dengan $group pipeline, lalu menggunakan $concat dengan $reduce pada larik yang dihasilkan dalam proyeksi akhir:

db.collection.aggregate([
  { "$group": {
    "_id": "$tag_id",
    "client_id": { "$push": "$client_id" }
  }},
  { "$addFields": {
    "client_id": {
      "$reduce": {
        "input": "$client_id",
        "initialValue": "",
        "in": {
          "$cond": {
            "if": { "$eq": [ "$$value", "" ] },
            "then": "$$this",
            "else": {
              "$concat": ["$$value", ",", "$$this"]
            }
          }
        }
      }
    }
  }}
])

Kami juga menerapkan $cond di sini untuk menghindari penggabungan string kosong dengan koma di hasil, sehingga lebih terlihat seperti daftar yang dibatasi.

FYI Ada masalah JIRA SERVER-29339 yang meminta $reduce untuk diimplementasikan sebagai ekspresi akumulator untuk mengizinkannya digunakan secara langsung di $group tahap pipa. Kemungkinan tidak akan terjadi dalam waktu dekat, tetapi secara teoritis akan menggantikan $push di atas dan membuat operasi satu tahap pipa. Contoh sintaks yang diusulkan ada di edisi JIRA.

Jika Anda tidak memiliki $reduce ( membutuhkan MongoDB 3.4 ) lalu cukup posting proses kursor:

db.collection.aggregate([
  { "$group": {
    "_id": "$tag_id",
    "client_id": { "$push": "$client_id" }
  }},
]).map( doc =>
  Object.assign(
    doc,
   { "client_id": doc.client_id.join(",") }
  )
)

Yang kemudian mengarah ke alternatif lain untuk melakukan ini menggunakan mapReduce jika Anda benar-benar harus:

db.collection.mapReduce(
  function() {
    emit(this.tag_id,this.client_id);
  },
  function(key,values) {
    return [].concat.apply([],values.map(v => v.split(","))).join(",");
  },
  { "out": { "inline": 1 } }
)

Yang tentu saja menghasilkan mapReduce tertentu bentuk _id dan value sebagai set kunci, tetapi pada dasarnya adalah output.

Kami menggunakan [].concat.apply([],values.map(...)) karena output dari "reducer" bisa berupa "delimited string" karena mapReduce bekerja secara bertahap dengan hasil yang besar dan oleh karena itu keluaran dari peredam dapat menjadi "masukan" pada lintasan lain. Jadi kita perlu berharap bahwa ini bisa terjadi dan memperlakukannya dengan semestinya.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Luwak findByIdAndUpdate tidak mengembalikan model yang benar

  2. Bagaimana cara menangkap MongoSecurityException?

  3. Pencarian mongodb data musim semi untuk tanggal ISO

  4. Pencarian MongoDB untuk setiap dict dalam daftar dalam koleksi

  5. Apakah MongoDB mendukung tipe floating point?