2011-08-30 23 views
23

Trong các tài liệu chính thức của MongoDB họ đề cập upserts, vì vậy nó sẽ thực sự tốt đẹp để viết một lệnh upsert thay vì:Upserting trong Mongo DB sử dụng chính thức C# tài xế

if (_campaignRepo.Exists(camp)) 
{ 
    _campaignRepo.DeleteByIdAndSystemId(camp); 
} 

_campaignRepo.Save(camp); 

cái gì đó mà sẽ thực hiện logic trên mức db nếu có thể. Vì vậy, cách để làm một upsert nếu có một là gì?

Trả lời

25

Đoạn mã dưới đây là từ một ứng dụng làm việc:

weekplanStore.Update(
    Query.EQ("weekNumber", week), 
    Update.Replace(rawWeekPlan), 
    UpdateFlags.Upsert); 

Các weekplanStore là bộ sưu tập MongoDB của tôi, và mã sẽ cập nhật các tài liệu tìm thấy với các truy vấn trong đối số đầu tiên hoặc chèn một cái mới nếu không tìm thấy. "Bí quyết" là sử dụng công cụ sửa đổi UpdateFlags.Upsert.

Các rawWeekPlan là đối tượng chèn hoặc cập nhật, và có các loại sau đây:

private class RawWeekPlan 
{ 
    public ObjectId id; 
    public int weekNumber; 
    public WeekPlanEntry[] entries; 
} 

và biến thành bson bởi trình điều khiển tự động.

+0

Nó có hoạt động cho các bộ sưu tập lồng nhau không? Bạn đã thử nó chưa? Bởi vì nó không làm việc cho họ trong trường hợp của tôi –

+0

Không biết. Tôi đã không thử nó trên bộ sưu tập lồng nhau. –

+0

Sự cố là trong id-s. Tôi hỏi một câu hỏi trên một thread khác –

39

Phiên bản 2 trình điều khiển MongoDB C# yêu cầu đặt cờ IsUpsert trong lệnh ghi. Ví dụ này sẽ upsert toàn bộ tài liệu.

var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } }; 
var result = await collection.ReplaceOneAsync(
    filter: new BsonDocument("_id", 123), 
    options: new UpdateOptions { IsUpsert = true } 
    replacement: newDoc); 

Phiên bản 1 của trình điều khiển MongoDB C# thực hiện logic này trong lệnh Save.

var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } }; 
collection.Save(newDoc); 

Các phương thức Save là sự kết hợp của Insert và Update. Nếu thành viên Id của tài liệu có giá trị, thì nó được giả định là tài liệu hiện có và Lưu cập nhật cuộc gọi trên tài liệu (thiết lập cờ Upsert chỉ trong trường hợp nó thực sự là tài liệu mới). Nếu không, nó được giả định là một tài liệu mới và Lưu các cuộc gọi Chèn sau khi gán một giá trị duy nhất mới được tạo ra cho thành viên Id.

tham khảo: http://mongodb.github.io/mongo-csharp-driver/1.11/driver/#save-tdocument-method

Lưu ý: Đây không yêu cầu các bản đồ thích hợp của lĩnh vực Id tuy nhiên. Thông tin thêm vào đó ở đây: http://mongodb.github.io/mongo-csharp-driver/1.11/serialization/#identifying-the-id-field-or-property

+0

Điều này không còn khả thi với API mới nữa. –

+0

Đã cập nhật. Mặc dù tôi nghĩ rằng API mới làm cho các lệnh upsert khó sử dụng hơn. –

+0

Điều gì được chuyển đến bộ lọc nếu ID newDocs là rỗng, tức là nó là một chèn? Chỉ là một tài liệu bson trống? – BenCr

5

Bạn có thể sử dụng lệnh cập nhật thường xuyên, nhưng chỉ cần vượt qua nó cập nhật cờ Upsert

MongoCollection collection = db.GetCollection("matches"); 
var query = new QueryDocument("recordId", recordId); 

var update = Update.Set("FirstName", "John").Set("LastName","Doe"); 
matchCollection.Update(query, update, UpdateFlags.Upsert, SafeMode.False); 

Đó là mã được chuyển thể từ một ứng dụng làm việc (rút ngắn cho rõ ràng)

21

Bắt đầu từ v2.0 của trình điều khiển có một API không đồng bộ mới. API cũ sẽ không còn được sử dụng vì nó là mặt tiền chặn trên API mới và không còn được dùng nữa.

Cách hiện khuyến khích để upsert một tài liệu là bằng cách gọi và chờ ReplaceOneAsync với cờ IsUpsert bật và một bộ lọc phù hợp với tài liệu có liên quan:

Hamster hamster = ... 
var replaceOneResult = await collection.ReplaceOneAsync(
    doc => doc.Id == hamster.Id, 
    hamster, 
    new UpdateOptions {IsUpsert = true}); 

Bạn có thể kiểm tra xem các hoạt động là một chèn hoặc cập nhật bằng cách xem ReplaceOneResult.MatchedCount:

+0

Tôi đang cố gắng sử dụng ReplaceOneAsync nhưng nó ném một ngoại lệ: "Tên phần tử" không hợp lệ ", tôi đang sử dụng bộ lọc cho updateOneasync nó hoạt động nhưng không phải với replaceone. Bạn có thể giúp tôi không? –

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