Dường như bạn nghĩ rằng có thể gọi một hàm JavaScript trong đường dẫn tổng hợp, nhưng bạn không thể thực hiện điều này. Bạn đang nhầm lẫn thực sự là "nội suy" của một biến từ kết quả hàm để thực thi trong đường dẫn.
Ví dụ:Nếu tôi làm điều này:
var getNumbers = function() { return [ 1,2,3 ] };
Sau đó, tôi gọi đây là:
db.collection.aggregate([
{ "$project": {
"mynums": getNumbers()
}}
])
Sau đó, những gì thực sự xảy ra trong JavaScript shell, các giá trị đang được "nội suy" và "trước khi" lệnh được gửi đến máy chủ, như sau:
db.collection.aggregate([
{ "$project": {
"mynums": [1,2,3]
}}
])
Để chứng minh thêm điều đó, hãy lưu trữ một hàm "chỉ" trên máy chủ:
db.system.js.save({ "_id": "hello", "value": function() { return "hello" } })
Sau đó, hãy thử chạy câu lệnh tổng hợp:
db.collection.aggregate([
{ "$project": {
"greeting": hello()
}}
])
Và điều đó sẽ dẫn đến một ngoại lệ:
E QUERY [main] ReferenceError:hello không được xác định tại (shell):1:69
Đó là vì việc thực thi đang diễn ra trên "máy khách" chứ không phải "máy chủ" và chức năng không tồn tại trên máy khách.
Khung tổng hợp không thể chạy JavaScript, vì nó không có quy định nào để làm như vậy. Tất cả các hoạt động được thực hiện bằng mã gốc, không có công cụ JavaScript nào được gọi. Do đó, bạn sử dụng các toán tử ở đó để thay thế:
db.collection.aggregate([
{ "$project": {
"total": { "$add": [ 1, 2 ] },
"field_total": { "$subtract": [ "$gross", "$tax" ] }
}}
])
Nếu bạn không thể sử dụng các toán tử để đạt được kết quả thì cách duy nhất bạn có thể chạy mã JavaScript là chạy mapReduce thay thế, tất nhiên là sử dụng công cụ JavaScript để giao tiếp với dữ liệu từ bộ sưu tập. Và từ đó, bạn cũng có thể tham khảo một chức năng phía máy chủ bên trong lôgic của mình nếu bạn cần:
{ "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 } }
)
Lợi nhuận:
{
"_id": 1,
"value": 14
}
Vì vậy, đây không phải là về "cách truyền giá trị trường" mà thực sự là về thực tế là khung tổng hợp không hỗ trợ JavaScript theo bất kỳ cách nào và những gì bạn nghĩ đang xảy ra thực tế không phải như vậy.