2017-01-10 12 views
5

truy vấn này được làm công việc tốt:

db.collection.update(
    { "_id": oneIdProvided }, 
    { $inc: { "field": 5 } },{ upsert: true } 
) 

Bây giờ tôi muốn làm các hoạt động cùng nhiều thời gian với các ID khác nhau, tôi nghĩ rằng cách tốt là sử dụng $ trong và do đó tôi đã cố gắng:

db.collection.update(
    { "_id": { $in: oneArrayOfIds} }, 
    { $inc: { "field": 5 } },{ upsert: true } 
) 

vấn đề là: nếu một trong các ID được cung cấp trong mảng không tồn tại trong bộ sưu tập, một tài liệu mới được tạo ra (đó là những gì tôi muốn) nhưng sẽ được gán cho một ID tự động, không sử dụng ID mà tôi đã cung cấp và đang tìm kiếm.

Một giải pháp tôi thấy có thể làm đầu tiên một truy vấn chèn với mảng của tôi về ID (những người đã tồn tại sẽ không được sửa đổi) và sau đó làm truy vấn cập nhật của tôi với upsert: false

Bạn có thấy một cách để làm điều đó chỉ trong một truy vấn?

Trả lời

2

Chúng tôi có thể thực hiện điều này bằng cách thực hiện nhiều thao tác ghi bằng phương pháp bulkWrite().

function* range(start, end, step) { 
    for (let val=start; val<end; val+=step) 
     yield val 
} 

let oneArrayOfIds; // For example [1, 2, 3, 4] 

let bulkOp = oneArrayOfIds.map(id => { 
    return { 
     "updateOne": { 
      "filter": { "_id": id }, 
      "update": { "$set": { "field": 5 } }, 
      "upsert": true 
     } 
    }; 
}); 

const limit = 1000; 
const len = bulkOp.length; 

let chunks = []; 
if (len > 1000) { 
    for (let index of range(0, len, limit)) { 
     db.collection.bulkWrite(bulkOp.slice(index, index+limit)); 
    } 
} else { 
    db.collection.bulkWrite(bulkOp); 
} 
+0

Cảm ơn bạn, bulkWrite() thực sự là những gì tôi đã bỏ lỡ ở đây. – Felwin

+1

Câu hỏi nhanh, trong ví dụ mã của bạn, bạn đang tạo hàng loạt 1000 yêu cầu để tránh giới hạn, tuy nhiên theo [tài liệu] (https://docs.mongodb.com/manual/reference/limits/#Write-Command-Operation -Limit-Size) Bước này không cần thiết nếu sử dụng trình điều khiển. Bạn có thể xác nhận các trình điều khiển đang thực sự xử lý phần đó và tôi có thể gọi một bulkWrite với hơn 1000 mục không? – Felwin

+1

Có, bạn có thể gửi hơn 1000 hoạt động và MongoDB sẽ thực hiện công việc cho bạn bằng cách chia nó thành một nhóm phụ 1000. Nhưng tôi thích tự mình làm. – styvane

Các vấn đề liên quan