Zdá se, že si myslíte, že je možné volat funkci JavaScriptu v agregačním kanálu, ale nemůžete to udělat. Mýlíte se, co je vlastně "interpolace" proměnné z výsledku funkce pro provádění v rámci kanálu.
Například když udělám toto:
var getNumbers = function() { return [ 1,2,3 ] };
Pak tomu říkám:
db.collection.aggregate([
{ "$project": {
"mynums": getNumbers()
}}
])
Poté, co se ve skutečnosti stane v prostředí JavaScriptu, hodnoty jsou „interpolovány“ a „před“ je instrukce odeslána na server, takto:
db.collection.aggregate([
{ "$project": {
"mynums": [1,2,3]
}}
])
Chcete-li to dále demonstrovat, uložte funkci „pouze“ na server:
db.system.js.save({ "_id": "hello", "value": function() { return "hello" } })
Potom zkuste spustit příkaz agregace:
db.collection.aggregate([
{ "$project": {
"greeting": hello()
}}
])
A to bude mít za následek výjimku:
E QUERY [main] ReferenceError:hello není definováno v (shell):1:69
Je to proto, že spouštění probíhá na "klientovi" a ne na "serveru" a funkce na klientovi neexistuje.
Agregační rámec nemůže spusťte JavaScript, protože k tomu nemá žádné ustanovení. Všechny operace jsou prováděny v nativním kódu, aniž by byl vyvolán žádný JavaScript engine. Proto tam místo toho použijete operátory:
db.collection.aggregate([
{ "$project": {
"total": { "$add": [ 1, 2 ] },
"field_total": { "$subtract": [ "$gross", "$tax" ] }
}}
])
Pokud nemůžete použít operátory k dosažení výsledků, pak jediným způsobem, jak můžete spustit kód JavaScript, je místo toho spustit mapReduce, který samozřejmě používá JavaScript engine pro propojení s daty z kolekce. A odtud můžete také odkazovat na funkci na straně serveru uvnitř vaší logiky, pokud potřebujete:
{ "key": 1, "value": 1 },
{ "key": 1, "value": 2 },
{ "key": 1, "value": 3 }
db.system.js.save({ "_id": "square", "value": function(num) { return num * num } })
db.collection.mapReduce(
function() {
emit(this.key,square(this.value))
},
function(key,values) {
return Array.sum(values);
},
{ "out": { "inline": 1 } }
)
Vrátí:
{
"_id": 1,
"value": 14
}
Nejde tedy o to „jak předat hodnotu pole“, ale ve skutečnosti o skutečnost, že agregační rámec žádným způsobem nepodporuje JavaScript a že to, co jste si mysleli, že se děje, ve skutečnosti není.