Кажется, вы думаете, что в конвейере агрегации можно вызвать функцию JavaScript, но вы не можете этого сделать. Вы ошибаетесь, что на самом деле является «интерполяцией» переменной из результата функции для выполнения внутри конвейера.
Например, если я это сделаю:
var getNumbers = function() { return [ 1,2,3 ] };
Затем я вызываю это :
db.collection.aggregate([
{ "$project": {
"mynums": getNumbers()
}}
])
Затем, что на самом деле происходит в оболочке JavaScript, значения «интерполируются» и «до» команда отправляется на сервер, например:
db.collection.aggregate([
{ "$project": {
"mynums": [1,2,3]
}}
])
Чтобы продемонстрировать это, сохраните функцию «только» на сервере:
db.system.js.save({ "_id": "hello", "value": function() { return "hello" } })
Затем попробуйте запустить оператор агрегации:
db.collection.aggregate([
{ "$project": {
"greeting": hello()
}}
])
И это приведет к Исключение:
E QUERY [main] ReferenceError: hello не определено в (shell): 1: 69
blockquote>Это потому, что выполнение выполняется на «клиент», а не «сервер», а функция не существует на клиенте.
В структуре агрегации не может запускаться JavaScript, так как у нее нет никаких условий для этого. Все операции выполняются в собственном коде без запуска JavaScript-движка. Поэтому вместо этого вы используете операторы:
db.collection.aggregate([ { "$project": { "total": { "$add": [ 1, 2 ] }, "field_total": { "$subtract": [ "$gross", "$tax" ] } }} ])
Если вы не можете использовать операторов для получения результатов, то единственный способ запустить код JavaScript - это запустить mapReduce вместо этого, который, конечно, использует механизм JavaScript для взаимодействия с данными из коллекции. И оттуда вы также можете ссылаться на функцию на стороне сервера в своей логике, если вам нужно:
{ "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 } } )
Возвраты:
{ "_id": 1, "value": 14 }
Так что это не о том, «как пройти в значении поля ", но на самом деле о том, что структура агрегации никак не поддерживает JavaScript и что то, что вы считали происходящим, на самом деле не так.