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

MongoDB tính điểm từ các trường hiện có và đưa nó vào một trường mới trong cùng một bộ sưu tập

Tùy thuộc vào nhu cầu ứng dụng của bạn, bạn có thể sử dụng khung tổng hợp để tính điểm và sử dụng BulWrite () để cập nhật bộ sưu tập của bạn. Hãy xem xét ví dụ sau sử dụng mã <> $ dự án bước đường ống dẫn như một sự nhàn rỗi cho các phép tính điểm số với các toán tử số học.

Vì logic để tính toán C3 trong câu hỏi của bạn là nhận được một số từ 1 thành 7 bằng chính xác 7 - số điểm (.) , cách tiếp cận khả thi duy nhất mà tôi có thể nghĩ đến là lưu trữ thêm một trường giữ giá trị này trước khi thực hiện tổng hợp. Vì vậy, bước đầu tiên của bạn sẽ là tạo trường bổ sung đó và bạn có thể tiếp tục bằng cách sử dụng BulWrite () như sau:

Bước 1:Sửa đổi giản đồ để chứa thêm daysInWeek lĩnh vực

var counter = 0, bulkUpdateOps = [];

db.collection1.find({
    "Field5": { "$exists": true }
}).forEach(function(doc) {
    // calculations for getting the number of points in Field5
    var points, daysInWeek;
    points = (doc.Field5.match(new RegExp(".", "g")) || []).length;
    daysInWeek = 7 - points;
    bulkUpdateOps.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": {
                "$set": { "daysInWeek": daysInWeek }
            }
        }
    });
    counter++;

    if (counter % 500 == 0) {
        db.collection1.bulkWrite(bulkUpdateOps);
        bulkUpdateOps = [];
    }
});

if (counter % 500 != 0) { db.collection1.bulkWrite(bulkUpdateOps); }

Lý tưởng nhất là thao tác trên cũng có thể phù hợp với việc tính toán các hằng số khác trong câu hỏi của bạn và do đó tạo ra Field8 kết quả là. Tuy nhiên, tôi tin rằng các phép tính như thế này nên được thực hiện trên máy khách và để MongoDB làm những gì nó hoạt động tốt nhất trên máy chủ.

Bước 2:Sử dụng tổng hợp để thêm Field8 lĩnh vực

Đã tạo trường bổ sung đó daysInWeek sau đó, bạn có thể xây dựng một đường dẫn tổng hợp dự báo các biến mới bằng cách sử dụng nhóm thuần tập toán tử số học để thực hiện tính toán (một lần nữa, bạn nên thực hiện các phép tính như vậy trên lớp ứng dụng). Phép chiếu cuối cùng sẽ là sản phẩm của các trường được tính toán mà sau đó bạn có thể sử dụng con trỏ kết quả tổng hợp để lặp lại và thêm Field8 vào bộ sưu tập với mỗi tài liệu:

var pipeline = [
        {
            "$project": {
                "C1": {
                    "$add": [ 
                        10, 
                        { "$multiply": [ "$Field3", 0.03 ] } 
                    ]
                },
                "C2": {
                    "$cond": [
                        { "$eq": [ "$Field2", 1 ] }, 
                        1, 
                        0.03 
                    ]
                },
                "C3": "$daysInWeek",
                "C4": {
                    "$cond": [
                        { "$eq": [ "$Field2", 1 ]  },
                        { "$pow": [ "$Field4", -0.6 ] },
                        1
                    ]
                }
            }
        },
        {
            "$project": {
                "Field8": { "$multiply": [ "$C1", "$C2", "$C3", "$C4" ] }
            }
        }
    ],
    counter = 0,
    bulkUpdateOps = [];

db.collection1.aggregate(pipeline).forEach(function(doc) {
    bulkUpdateOps.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": {
                "$set": { "Field8": doc.Field8 }
            }
        }
    });
    counter++;

    if (counter % 500 == 0) {
        db.collection1.bulkWrite(bulkUpdateOps);
        bulkUpdateOps = [];
    }
});

if (counter % 500 != 0) { db.collection1.bulkWrite(bulkUpdateOps); }

Đối với MongoDB > =2.6 <=3.0 , sử dụng API hoạt động hàng loạt nơi bạn cần lặp lại bộ sưu tập bằng cách sử dụng của con trỏ forEach () phương pháp, cập nhật từng tài liệu trong bộ sưu tập.

Một số toán tử số học từ đường ống tổng hợp ở trên không khả dụng trong MongoDB > =2.6 <=3.0 vì vậy bạn sẽ cần thực hiện các phép tính trong forEach () sự lặp lại.

Sử dụng API hàng loạt để giảm yêu cầu ghi của máy chủ bằng cách nhóm từng bản cập nhật hàng loạt và chỉ gửi đến máy chủ một lần trong mỗi 500 tài liệu trong bộ sưu tập để xử lý:

var bulkUpdateOps = db.collection1.initializeUnorderedBulkOp(),
    cursor = db.collection1.find(), // cursor 
    counter = 0;

cursor.forEach(function(doc) {
    // computations
    var c1, c2, c3, c4, Field8;
    c1 = 10 + (0.03*doc.Field3);
    c2 = (doc.Field2 == 1) ? 1: 0.03;
    c3 = 7 - (doc.Field5.match(new RegExp(".", "g")) || []).length;
    c4 = (doc.Field2 == 1) ? Math.pow(doc.Field, -0.6) : 1;
    Field8 = c1*c2*c3*c4;

    bulkUpdateOps.find({ "_id": doc._id }).updateOne({
        "$set": { "Field8": Field8 }
    });

    if (counter % 500 == 0) {
        bulkUpdateOps.execute();
        bulkUpdateOps = db.collection1.initializeUnorderedBulkOp();
    }
})

if (counter % 500 != 0) { bulkUpdateOps.execute(); }    


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. ký tự đại diện tiền tố mongoDB:fulltext-search ($ text) tìm một phần với chuỗi tìm kiếm

  2. Làm cách nào để xoay vòng trên MongoDB

  3. mongo dot ký hiệu không rõ ràng

  4. Thành viên mới không thể tải JSON

  5. mongodb cho phép kết nối khách ngay cả khi auth được bật