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

MongoDB - Gunakan kerangka kerja agregasi atau mapreduce untuk mencocokkan array string dalam dokumen (pencocokan profil)

MapReduce akan menjalankan JavaScript di utas terpisah dan menggunakan kode yang Anda berikan untuk memancarkan dan mengurangi bagian dari dokumen Anda untuk digabungkan pada bidang tertentu. Anda tentu dapat melihat latihan sebagai agregasi atas setiap "nilai bidang". Kerangka kerja agregasi dapat melakukan ini juga tetapi akan jauh lebih cepat karena agregasi akan berjalan di server dalam C++ daripada di utas JavaScript yang terpisah. Tetapi kerangka kerja agregasi dapat mengembalikan lebih banyak data daripada 16 MB dalam hal ini Anda perlu melakukan partisi kumpulan data yang lebih kompleks.

Tapi sepertinya masalahnya jauh lebih sederhana dari ini. Anda hanya ingin menemukan untuk setiap profil apa profil lain berbagi atribut tertentu dengannya - tanpa mengetahui ukuran kumpulan data Anda, dan persyaratan kinerja Anda, saya akan berasumsi bahwa Anda memiliki indeks pada fieldValues ​​sehingga akan efisien untuk melakukan kueri di atasnya dan kemudian Anda bisa mendapatkan hasil yang Anda inginkan dengan loop sederhana ini:

> db.profiles.find().forEach( function(p) { 
       print("Matching profiles for "+tojson(p));
       printjson(
            db.profiles.find(
               {"fieldValues": {"$in" : p.fieldValues},  
                                "_id" : {$gt:p._id}}
            ).toArray()
       ); 
 }  );

Keluaran:

Matching profiles for {
    "_id" : 1,
    "firstName" : "John",
    "lastName" : "Smith",
    "fieldValues" : [
        "favouriteColour|red",
        "food|pizza",
        "food|chinese"
    ]
}
[
    {
        "_id" : 2,
        "firstName" : "Sarah",
        "lastName" : "Jane",
        "fieldValues" : [
            "favouriteColour|blue",
            "food|pizza",
            "food|mexican",
            "pets|yes"
        ]
    },
    {
        "_id" : 3,
        "firstName" : "Rachel",
        "lastName" : "Jones",
        "fieldValues" : [
            "food|pizza"
        ]
    }
]
Matching profiles for {
    "_id" : 2,
    "firstName" : "Sarah",
    "lastName" : "Jane",
    "fieldValues" : [
        "favouriteColour|blue",
        "food|pizza",
        "food|mexican",
        "pets|yes"
    ]
}
[
    {
        "_id" : 3,
        "firstName" : "Rachel",
        "lastName" : "Jones",
        "fieldValues" : [
            "food|pizza"
        ]
    }
]
Matching profiles for {
    "_id" : 3,
    "firstName" : "Rachel",
    "lastName" : "Jones",
    "fieldValues" : [
        "food|pizza"
    ]
}
[ ]

Jelas Anda dapat mengubah kueri agar tidak mengecualikan profil yang sudah cocok (dengan mengubah {$gt:p._id} ke {$ne:{p._id}} dan tweak lainnya. Tapi saya tidak yakin nilai tambahan apa yang akan Anda dapatkan dari menggunakan kerangka kerja agregasi atau mapreduce karena ini tidak benar-benar menggabungkan satu koleksi di salah satu bidangnya (dilihat dari format output yang Anda tampilkan). Jika persyaratan format output Anda fleksibel, tentu Anda dapat menggunakan salah satu opsi agregasi bawaan juga.

Saya memang memeriksa untuk melihat seperti apa ini jika menggabungkan di sekitar masing-masing fieldValues ​​dan itu tidak buruk, mungkin membantu Anda jika output Anda dapat cocok dengan ini:

> db.profiles.aggregate({$unwind:"$fieldValues"}, 
      {$group:{_id:"$fieldValues", 
              matchedProfiles : {$push:
               {  id:"$_id", 
                  name:{$concat:["$firstName"," ", "$lastName"]}}},
                  num:{$sum:1}
               }}, 
      {$match:{num:{$gt:1}}});
{
    "result" : [
        {
            "_id" : "food|pizza",
            "matchedProfiles" : [
                {
                    "id" : 1,
                    "name" : "John Smith"
                },
                {
                    "id" : 2,
                    "name" : "Sarah Jane"
                },
                {
                    "id" : 3,
                    "name" : "Rachel Jones"
                }
            ],
            "num" : 3
        }
    ],
    "ok" : 1
}

Ini pada dasarnya mengatakan "Untuk setiap fieldValue ($unwind) kelompokkan dengan fieldValue array profil yang cocok _id dan nama, menghitung berapa banyak kecocokan yang dikumpulkan setiap fieldValue ($grup) dan kemudian mengecualikan yang hanya memiliki satu profil yang cocok.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Praktik terbaik NoSQL

  2. Bagaimana cara menyimpan array objek ke DB luwak hanya dengan satu panggilan?

  3. Cara menggunakan mongoimport untuk mengimpor csv

  4. Bagaimana cara mengurutkan array di dalam catatan koleksi di MongoDB?

  5. Gunakan JsonConverter secara global di kelas tanpa atribut