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

Tổng số các di tích phụ ở Mongoose

Sử dụng tổng hợp () , bạn có thể chạy đường dẫn sau sử dụng $ sum toán tử để có được kết quả mong muốn:

const results = await Cart.aggregate([
    { "$addFields": {
        "totalPrice": {
            "$sum": "$products.subTotal"
        }
    } },
]);

console.log(JSON.stringify(results, null, 4));

và thao tác cập nhật tương ứng như sau:

db.carts.updateMany(
   { },
   [
        { "$set": {
            "totalPrice": {
                "$sum": "$products.subTotal"
            }
        } },
    ]
)

Hoặc nếu sử dụng MongoDB 3.2 và các phiên bản cũ hơn, trong đó $ sum chỉ khả dụng ở vòng bảng $, bạn có thể thực hiện

const pipeline = [
    { "$unwind": "$products" },
    {
        "$group": {
            "_id": "$_id",
            "products": { "$push": "$products" },
            "userPurchased": { "$first": "$userPurchased" },
            "totalPrice": { "$sum": "$products.subTotal" }
        }
    }
]

Cart.aggregate(pipeline)
    .exec(function(err, results){
        if (err) throw err;
        console.log(JSON.stringify(results, null, 4));
    })

Trong quy trình trên, bước đầu tiên là $ unwind nhà điều hành

{ "$unwind": "$products" }

điều này khá tiện dụng khi dữ liệu được lưu trữ dưới dạng mảng. Khi toán tử thư giãn được áp dụng trên trường dữ liệu danh sách, nó sẽ tạo một bản ghi mới cho từng và mọi phần tử của trường dữ liệu danh sách mà thao tác thư giãn được áp dụng. Về cơ bản, nó làm phẳng dữ liệu.

Đây là thao tác cần thiết cho giai đoạn tiếp theo, $ group bước nơi bạn nhóm các tài liệu được làm phẳng theo _id , do đó, tập hợp lại một cách hiệu quả các tài liệu không chuẩn hóa trở lại lược đồ ban đầu của chúng.

$ group toán tử đường ống tương tự như GROUP BY của SQL mệnh đề. Trong SQL, bạn không thể sử dụng GROUP BY trừ khi bạn sử dụng bất kỳ hàm tổng hợp nào. Theo cách tương tự, bạn cũng phải sử dụng một hàm tổng hợp trong MongoDB (được gọi là bộ tích lũy). Bạn có thể đọc thêm về bộ tích lũy tại đây .

Trong $ group này hoạt động, logic để tính toán totalPrice và việc trả lại các trường gốc thông qua bộ tích lũy . Bạn nhận được totalPrice bằng cách cộng gộp từng subTotal riêng lẻ các giá trị cho mỗi nhóm với $ sum như:

"totalPrice": { "$sum": "$products.subTotal }

Biểu thức khác

"userPurchased": { "$first": "$userPurchased" },

sẽ trả về một userPurchased giá trị từ tài liệu đầu tiên cho mỗi nhóm bằng cách sử dụng $ first . Do đó, việc xây dựng lại một cách hiệu quả giản đồ tài liệu gốc trước $ thư giãn

Một điều cần lưu ý ở đây là khi thực hiện một đường ống, MongoDB đưa các nhà khai thác vào nhau. "Pipe" ở đây mang nghĩa Linux:đầu ra của một toán tử trở thành đầu vào của toán tử sau. Kết quả của mỗi toán tử là một tập hợp tài liệu mới. Vì vậy Mongo thực hiện đường dẫn trên như sau:

Bộ sưu tập
collection | $unwind | $group => result

Lưu ý thêm, để giúp hiểu đường ống hoặc gỡ lỗi nếu bạn nhận được kết quả không mong muốn, hãy chạy tổng hợp chỉ với nhà điều hành đường ống đầu tiên. Ví dụ:chạy tổng hợp trong mongo shell dưới dạng:

db.cart.aggregate([
    { "$unwind": "$products" }
])

Kiểm tra kết quả để xem liệu các sản phẩm mảng được giải cấu trúc đúng cách. Nếu điều đó mang lại kết quả mong đợi, hãy thêm phần tiếp theo:

db.cart.aggregate([
    { "$unwind": "$products" },
    {
        "$group": {
            "_id": "$_id",
            "products": { "$push": "$products" },
            "userPurchased": { "$first": "$userPurchased" },
            "totalPrice": { "$sum": "$products.subTotal" }
        }
    }
])

Lặp lại các bước cho đến khi bạn đến bước cuối cùng.

Nếu bạn muốn cập nhật trường thì bạn có thể thêm $ out bước cuối cùng. Thao tác này sẽ ghi các tài liệu kết quả của quy trình tổng hợp vào cùng một bộ sưu tập, do đó cập nhật bộ sưu tập về mặt kỹ thuật.

var pipeline = [
    { "$unwind": "$products" },
    {
        "$group": {
            "_id": "$_id",
            "products": { "$push": "$products" },
            "userPurchased": { "$first": "$userPurchased" },
            "totalPrice": { "$sum": "$products.subTotal" }
        }
    },
    { "$out": "cart" } // write the results to the same underlying mongo collection
]

CẬP NHẬT

Để thực hiện cả cập nhật và truy vấn, bạn có thể phát hành một find () gọi lại trong cuộc gọi lại tổng hợp để nhận json cập nhật tức là

Cart.aggregate(pipeline)
    .exec(function(err, results){
        if (err) throw err;
        Cart.find().exec(function(err, docs){
            if (err) return handleError(err);
            console.log(JSON.stringify(docs, null, 4));
        })
    })
    

Sử dụng Promises, bạn có thể thực hiện việc này theo cách khác như

Cart.aggregate(pipeline).exec().then(function(res)
    return Cart.find().exec();
).then(function(docs){  
    console.log(JSON.stringify(docs, null, 4));
});


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Lỗi khi cài đặt trình điều khiển mongo cho PHP trên amazon linux

  2. Tạo Chỉ mục không gian địa lý 2dsphere cho các truy vấn hình cầu trong MongoDB

  3. MongoDB:Cập nhật ngữ nghĩa Công cụ sửa đổi của $ unset

  4. Trình điều khiển gốc tìm thấy từ mô hình Mongoose không trả về Con trỏ

  5. Truy vấn MongoDB để viết hoa chữ cái đầu tiên trong cơ sở dữ liệu hiện có