MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Sử dụng các hàm JavaScript được lưu trữ trong đường dẫn Tổng hợp, MapReduce hoặc runCommand

Bất kỳ chức năng nào bạn lưu vào system.js có sẵn để sử dụng bởi các câu lệnh xử lý "JavaScript" chẳng hạn như $where toán tử và mapReduce và có thể được tham chiếu bởi _id giá trị được chỉ định.

db.system.js.save({ 
   "_id": "squareThis", 
   "value": function(a) { return a*a } 
})

Và một số dữ liệu được chèn vào bộ sưu tập "mẫu":

{ "_id" : ObjectId("55aafd2bacbed38e06f9eccf"), "a" : 1 }
{ "_id" : ObjectId("55aafea6acbed38e06f9ecd0"), "a" : 2 }
{ "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 }

Sau đó:

db.sample.mapReduce(
    function() {
       emit(null, squareThis(this.a));
    },
    function(key,values) {
        return Array.sum(values);
    },
    { "out": { "inline": 1 } }
 );

Cung cấp:

   "results" : [
            {
                    "_id" : null,
                    "value" : 14
            }
    ],

Hoặc với $where :

db.sample.find(function() { return squareThis(this.a) == 9 })
{ "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 }

Nhưng trong trường hợp "không phải", bạn có thể sử dụng toàn cầu như cơ sở dữ liệu db tham chiếu hoặc các chức năng khác. Cả $wheremapReduce tài liệu chứa thông tin về giới hạn của những gì bạn có thể làm ở đây. Vì vậy, nếu bạn nghĩ rằng bạn sẽ làm điều gì đó như "tra cứu dữ liệu trong một bộ sưu tập khác", thì bạn có thể quên nó đi vì nó là "Không được phép".

Mọi Hành động lệnh MongoDB thực sự là dù sao một lời gọi đến một hành động "runCommand" "dưới mui xe". Nhưng trừ khi lệnh đó thực sự đang làm là "gọi một công cụ xử lý JavaScript" thì việc sử dụng trở nên không liên quan. Dù sao thì cũng chỉ có một số lệnh thực hiện việc này, là mapReduce , group hoặc eval và tất nhiên là các thao tác tìm với $where .

Khung tổng hợp không sử dụng JavaScript theo bất kỳ cách nào. Bạn có thể nhầm lẫn khi những người khác đã thực hiện một tuyên bố như thế này, điều này không đúng với những gì bạn nghĩ:

db.sample.aggregate([
    { "$match": {
        "a": { "$in": db.sample.distinct("a") }
    }}
])

Vì vậy, đó là "không chạy bên trong " đường dẫn tổng hợp, mà là "kết quả" của .distinct() đó cuộc gọi được "đánh giá" trước khi đường dẫn được gửi đến máy chủ. Nhiều như với một biến bên ngoài vẫn được thực hiện:

var items = [1,2,3];
db.sample.aggregate([
    { "$match": {
        "a": { "$in": items }
    }}
])

Về cơ bản, cả hai đều gửi đến máy chủ theo cùng một cách:

db.sample.aggregate([
    { "$match": {
        "a": { "$in": [1,2,3] }
    }}
])

Vì vậy, "không thể" gọi bất kỳ hàm JavaScript nào trong quy trình tổng hợp, cũng như không thực sự có điểm nào là "chuyển vào" kết quả nói chung từ thứ được lưu trong system.js . "Mã" cần được "tải tới máy khách" và chỉ một công cụ JavaScript mới thực sự có thể làm bất cứ điều gì với nó.

Với khung tổng hợp, tất cả các "toán tử" có sẵn thực sự là các hàm được mã hóa nguyên bản trái ngược với cách diễn giải JavaScript "biểu mẫu tự do" được cung cấp cho mapReduce . Vì vậy, thay vì viết "JavaScript", bạn sử dụng chính các toán tử:

db.sample.aggregate([
    { "$group": {
        "_id": null,
        "sqared": { "$sum": {
           "$multiply": [ "$a", "$a" ]
        }}
    }}
])

{ "_id" : null, "sqared" : 14 }

Vì vậy, có những hạn chế về những gì bạn có thể làm với các hàm được lưu trong system.js và rất có thể những gì bạn muốn làm là:

  • Không được phép, chẳng hạn như truy cập dữ liệu từ một bộ sưu tập khác
  • Không thực sự bắt buộc vì logic nói chung là độc lập
  • Hoặc có thể được triển khai tốt hơn theo logic ứng dụng khách hoặc các hình thức khác

Chỉ về cách sử dụng thực tế duy nhất mà tôi thực sự có thể nghĩ đến là bạn có một số hoạt động "mapReduce" không thể thực hiện theo bất kỳ cách nào khác và bạn có nhiều chức năng "chia sẻ" khác nhau mà bạn muốn chỉ lưu trữ trên máy chủ hơn là duy trì trong mỗi lệnh gọi hàm mapReduce.

Nhưng một lần nữa, 90% lý do khiến mapReduce trên khung tổng hợp thường là "cấu trúc tài liệu" của các bộ sưu tập đã được chọn kém và chức năng JavaScript là "cần thiết" để duyệt qua tài liệu để tìm kiếm và phân tích.

Vì vậy, bạn có thể sử dụng nó trong các ràng buộc cho phép, nhưng trong hầu hết các trường hợp, bạn có thể không nên sử dụng tính năng này mà hãy khắc phục các vấn đề khác khiến bạn tin rằng bạn cần tính năng này ngay từ đầu.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Truy vấn Mongo sử dụng mongoid trong ứng dụng rails gây ra lỗi hết thời gian chờ con trỏ

  2. Nhà điều hành đường ống tổng hợp MongoDB $ lt

  3. MongoDB findOneAndReplace ()

  4. MongoDB $ trong Toán tử truy vấn

  5. Các ABC của NestJS:Hướng dẫn cho người mới bắt đầu với MongoDB (Mongoose).