Всяка функция, която запазите в system.js
е наличен за използване от оператори за обработка на "JavaScript", като например $where
оператор и mapReduce
и може да бъде препратен от _id
е присвоена стойност.
db.system.js.save({
"_id": "squareThis",
"value": function(a) { return a*a }
})
И някои данни, вмъкнати в колекцията „извадка“:
{ "_id" : ObjectId("55aafd2bacbed38e06f9eccf"), "a" : 1 }
{ "_id" : ObjectId("55aafea6acbed38e06f9ecd0"), "a" : 2 }
{ "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 }
След това:
db.sample.mapReduce(
function() {
emit(null, squareThis(this.a));
},
function(key,values) {
return Array.sum(values);
},
{ "out": { "inline": 1 } }
);
Дава:
"results" : [
{
"_id" : null,
"value" : 14
}
],
Или с $where
:
db.sample.find(function() { return squareThis(this.a) == 9 })
{ "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 }
Но в "нито един" случай можете да използвате глобални като базата данни db
справочни или други функции. И двете $where
и mapReduce
документацията съдържа информация за границите на това, което можете да правите тук. Така че, ако сте мислили, че ще направите нещо като „потърсете данни в друга колекция“, тогава можете да го забравите, защото е „Не е разрешено“.
Всяка Командното действие на MongoDB всъщност е извикване на действие "runCommand" "под капака" така или иначе. Но освен ако това, което тази команда всъщност прави, не е „извикване на машина за обработка на JavaScript“, тогава използването става без значение. Все пак има само няколко команди, които правят това, като mapReduce
, group
или eval
, и разбира се операциите за намиране с $where
.
Рамката за агрегиранене използвайте JavaScript по какъвто и да е начин. Може да грешите точно както други са направили изявление като това, което не прави това, което смятате, че прави:
db.sample.aggregate([
{ "$match": {
"a": { "$in": db.sample.distinct("a") }
}}
])
Така че това е „не работи вътре " конвейера за агрегиране, а по-скоро "резултата" от този .distinct()
повикването се "оценява", преди конвейерът да бъде изпратен към сървъра. Както и с външна променлива се прави така или иначе:
var items = [1,2,3];
db.sample.aggregate([
{ "$match": {
"a": { "$in": items }
}}
])
И двете по същество изпращат до сървъра по един и същи начин:
db.sample.aggregate([
{ "$match": {
"a": { "$in": [1,2,3] }
}}
])
Така че "не е възможно" да се "извика" която и да е функция на JavaScript в конвейера за агрегиране, нито наистина има смисъл "предаване" на резултатите като цяло от нещо, запазено в system.js
. „Кодът“ трябва да бъде „зареден на клиента“ и само JavaScript машина може да направи нещо с него.
С рамката за агрегиране всички налични "оператори" всъщност са естествено кодирани функции, за разлика от интерпретацията на JavaScript в "свободна форма", предоставена за mapReduce
. Така че вместо да пишете "JavaScript", вие използвате самите оператори:
db.sample.aggregate([
{ "$group": {
"_id": null,
"sqared": { "$sum": {
"$multiply": [ "$a", "$a" ]
}}
}}
])
{ "_id" : null, "sqared" : 14 }
Така че има ограничения за това, което можете да правите с функциите, запазени в system.js, и има вероятност това, което искате да направите, е едно от следните:
- Не е разрешено, като например достъп до данни от друга колекция
- Всъщност не се изисква, тъй като логиката обикновено е самостоятелна
- Или вероятно все пак по-добре имплементиран в клиентска логика или друга различна форма
Почти единствената практическа употреба, за която наистина се сещам, е, че имате редица операции "mapReduce", които не могат да бъдат направени по друг начин и имате различни "споделени" функции, които бихте предпочели просто да съхранявате на сървъра, отколкото да поддържате във всеки Извикване на функция mapReduce.
Но отново, 90-процентната причина за mapReduce над рамката за агрегиране обикновено е, че „структурата на документа“ на колекциите е недобре избрана и JavaScript функционалността е „изисква“ за преминаване през документа за търсене и анализ.
Така че можете да го използвате при разрешените ограничения, но в повечето случаи вероятно изобщо не трябва да го използвате, а да коригирате другите проблеми, които са ви накарали да повярвате, че имате нужда от тази функция на първо място.