Fungsi apa pun yang Anda simpan ke system.js
tersedia untuk digunakan oleh pernyataan pemrosesan "JavaScript" seperti $where
operator dan mapReduce
dan dapat dirujuk oleh _id
nilai telah ditetapkan.
db.system.js.save({
"_id": "squareThis",
"value": function(a) { return a*a }
})
Dan beberapa data dimasukkan ke koleksi "sampel":
{ "_id" : ObjectId("55aafd2bacbed38e06f9eccf"), "a" : 1 }
{ "_id" : ObjectId("55aafea6acbed38e06f9ecd0"), "a" : 2 }
{ "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 }
Kemudian:
db.sample.mapReduce(
function() {
emit(null, squareThis(this.a));
},
function(key,values) {
return Array.sum(values);
},
{ "out": { "inline": 1 } }
);
Memberikan:
"results" : [
{
"_id" : null,
"value" : 14
}
],
Atau dengan $where
:
db.sample.find(function() { return squareThis(this.a) == 9 })
{ "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 }
Tetapi dalam kasus "tidak keduanya" Anda dapat menggunakan global seperti database db
referensi atau fungsi lainnya. Keduanya $where
dan mapReduce
dokumentasi berisi informasi tentang batasan apa yang dapat Anda lakukan di sini. Jadi, jika Anda berpikir akan melakukan sesuatu seperti "mencari data di koleksi lain", Anda dapat melupakannya karena "Tidak Diizinkan".
Setiap Tindakan perintah MongoDB sebenarnya panggilan ke tindakan "runCommand" "di bawah tenda". Tetapi kecuali apa yang sebenarnya dilakukan oleh perintah itu adalah "memanggil mesin pemrosesan JavaScript" maka penggunaannya menjadi tidak relevan. Hanya ada beberapa perintah yang melakukan ini, yaitu mapReduce
, group
atau eval
, dan tentu saja operasi find dengan $where
.
Kerangka kerja agregasi tidak gunakan JavaScript dengan cara apa pun. Anda mungkin salah seperti orang lain telah melakukan pernyataan seperti ini, yang tidak melakukan apa yang Anda pikirkan:
db.sample.aggregate([
{ "$match": {
"a": { "$in": db.sample.distinct("a") }
}}
])
Jadi itu "tidak berjalan di dalam " pipa agregasi, melainkan "hasil" dari .distinct()
. itu panggilan "dievaluasi" sebelum pipa dikirim ke server. Sama seperti dengan variabel eksternal dilakukan pula:
var items = [1,2,3];
db.sample.aggregate([
{ "$match": {
"a": { "$in": items }
}}
])
Keduanya pada dasarnya mengirim ke server dengan cara yang sama:
db.sample.aggregate([
{ "$match": {
"a": { "$in": [1,2,3] }
}}
])
Jadi "tidak mungkin" untuk "memanggil" fungsi JavaScript apa pun dalam pipa agregasi, juga tidak ada gunanya "melewati" hasil secara umum dari sesuatu yang disimpan di system.js
. "Kode" perlu "dimuat ke klien" dan hanya mesin JavaScript yang benar-benar dapat melakukan apa pun dengannya.
Dengan kerangka kerja agregasi, semua "operator" yang tersedia sebenarnya adalah fungsi kode asli yang bertentangan dengan interpretasi JavaScript "bentuk bebas" yang disediakan untuk mapReduce
. Jadi, alih-alih menulis "JavaScript", Anda menggunakan operator itu sendiri:
db.sample.aggregate([
{ "$group": {
"_id": null,
"sqared": { "$sum": {
"$multiply": [ "$a", "$a" ]
}}
}}
])
{ "_id" : null, "sqared" : 14 }
Jadi ada batasan pada apa yang dapat Anda lakukan dengan fungsi yang disimpan di system.js, dan kemungkinan yang ingin Anda lakukan adalah:
- Tidak diizinkan, seperti mengakses data dari koleksi lain
- Tidak terlalu diperlukan karena logika umumnya mandiri
- Atau mungkin lebih baik diimplementasikan dalam logika klien atau bentuk lain yang berbeda
Satu-satunya penggunaan praktis yang benar-benar dapat saya pikirkan adalah bahwa Anda memiliki sejumlah operasi "mapReduce" yang tidak dapat dilakukan dengan cara lain dan Anda memiliki berbagai fungsi "bersama" yang lebih suka Anda simpan di server daripada dipertahankan di setiap panggilan fungsi mapReduce.
Tetapi sekali lagi, 90% alasan mapReduce di atas kerangka agregasi biasanya karena "struktur dokumen" dari koleksi telah dipilih dengan buruk dan fungsionalitas JavaScript "diperlukan" untuk melintasi dokumen untuk pencarian dan analisis.
Jadi Anda dapat menggunakannya di bawah batasan yang diizinkan, tetapi dalam banyak kasus Anda mungkin tidak boleh menggunakan ini sama sekali, tetapi memperbaiki masalah lain yang membuat Anda yakin bahwa Anda membutuhkan fitur ini sejak awal.