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

Menggabungkan nilai string dalam array dalam satu bidang di MongoDB

Dalam rilis MongoDB Modern Anda bisa. Anda masih tidak dapat "secara langsung" menerapkan larik ke $concat , namun Anda dapat menggunakan $reduce untuk bekerja dengan elemen array dan menghasilkan ini:

db.collection.aggregate([
  { "$addFields": {
    "values": { 
      "$reduce": {
        "input": "$values",
        "initialValue": "",
        "in": {
          "$cond": {
            "if": { "$eq": [ { "$indexOfArray": [ "$values", "$$this" ] }, 0 ] },
            "then": { "$concat": [ "$$value", "$$this" ] },
            "else": { "$concat": [ "$$value", "_", "$$this" ] }
          }    
        }
      }        
    }
  }}
])

Menggabungkan tentu saja dengan $indexOfArray untuk tidak "gabungkan" dengan "_" menggarisbawahi ketika itu adalah indeks "pertama" dari array.

Juga "keinginan" tambahan saya telah dijawab dengan $sum :

db.collection.aggregate([
  { "$addFields": {
    "total": { "$sum": "$items.value" }
  }}
])

Jenis ini sedikit dimunculkan secara umum dengan operator agregasi yang mengambil array item. Perbedaannya di sini adalah bahwa itu berarti "array" dari "agumen" yang disediakan dalam representasi kode yang bertentangan dengan "elemen array" yang ada dalam dokumen saat ini.

Satu-satunya cara Anda benar-benar dapat melakukan jenis rangkaian item dalam array yang ada di dokumen adalah dengan melakukan semacam opsi JavaScript, seperti contoh ini di mapReduce:

db.collection.mapReduce(
    function() {
        emit( this._id, { "values": this.values.join("_") } );
    },
    function() {},
    { "out": { "inline": 1 } }
)

Tentu saja jika Anda tidak benar-benar menggabungkan apa pun, maka mungkin pendekatan terbaik adalah dengan melakukan operasi "bergabung" itu dalam kode klien Anda setelah memproses hasil kueri Anda. Tetapi jika perlu digunakan dalam beberapa tujuan di seluruh dokumen maka mapReduce akan menjadi satu-satunya tempat Anda dapat menggunakannya.

Saya dapat menambahkan bahwa "misalnya" Saya ingin sesuatu seperti ini berfungsi:

{
    "items": [
        { "product": "A", "value": 1 },
        { "product": "B", "value": 2 },
        { "product": "C", "value": 3 }
    ]
}

Dan secara agregat:

db.collection.aggregate([
    { "$project": {
        "total": { "$add": [
            { "$map": {
                "input": "$items",
                "as": "i",
                "in": "$$i.value"
            }}
        ]}
    }}
])

Tapi itu tidak berhasil karena $add mengharapkan argumen yang bertentangan dengan array dari dokumen. Mendesah! :(. Bagian dari alasan "berdasarkan desain" untuk ini dapat dikatakan bahwa "hanya karena" itu adalah array atau "daftar" nilai tunggal yang diteruskan dari hasil transformasi, tidak "dijamin" bahwa itu adalah sebenarnya "valid" nilai tipe numerik tunggal yang diharapkan operator. Setidaknya tidak pada metode "pemeriksaan tipe" yang diterapkan saat ini.

Artinya untuk saat ini kita masih harus melakukan ini:

db.collection.aggregate([
   { "$unwind": "$items" },
   { "$group": {
       "_id": "$_id",
        "total": { "$sum": "$items.value" }
   }}
])

Dan sayangnya juga tidak akan ada cara untuk menerapkan operator pengelompokan seperti itu untuk menggabungkan string.

Jadi, Anda dapat mengharapkan semacam perubahan dalam hal ini, atau mengharapkan beberapa perubahan yang memungkinkan variabel lingkup eksternal diubah dalam lingkup $map operasi dalam beberapa cara. Lebih baik lagi $join baru operasi akan diterima juga. Tetapi ini tidak ada pada saat penulisan, dan mungkin tidak akan ada untuk beberapa waktu mendatang.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bagaimana meningkatkan kinerja sisipan MongoDB

  2. Cara menangkap pengecualian saat membuat instance MongoClient

  3. Bagaimana cara mendapatkan data ReferenceField di mongoengine?

  4. MongoDB - Beberapa $atau operasi

  5. SQL NULLIF() Dijelaskan