2015-07-16 19 views
10

CHỈNH SỬA: Không tìm cách làm javascript này. Tôi đang tìm cách trình điều khiển MongoDB C# 2.0 để làm điều này (tôi biết điều đó có thể không khả thi, nhưng tôi hy vọng ai đó biết một giải pháp).Phần tử cập nhật Mongo (Trình điều khiển .NET 2.0)

Tôi đang cố gắng cập nhật giá trị của một mục được nhúng trong một mảng trên tài liệu chính trong mongodb của tôi.

Tôi đang tìm cách được nhập mạnh mẽ để thực hiện việc này. Tôi đang sử dụng Mongodb c# 2.0 driver

Tôi có thể làm điều đó bằng cách popping phần tử, cập nhật giá trị, sau đó lắp lại. Điều này không cảm thấy đúng; kể từ khi tôi ghi đè lên những gì có thể đã được viết trong thời gian chờ đợi.

Dưới đây là những gì tôi đã cố gắng cho đến nay nhưng không có may mắn:

private readonly IMongoCollection<TempAgenda> _collection; 

void Main() 
{ 
    var collectionName = "Agenda"; 
    var client = new MongoClient("mongodb://localhost:27017"); 
    var db = client.GetDatabase("Test"); 
    _collection = db.GetCollection<TempAgenda>(collectionName); 
    UpdateItemTitle(1, 1, "hello"); 
} 

public void UpdateItemTitle(string agendaId, string itemId, string title){ 
    var filter = Builders<TempAgenda>.Filter.Eq(x => x.AgendaId, agendaId); 
    var update = Builders<TempAgenda>.Update.Set(x => x.Items.Single(p => p.Id.Equals(itemId)).Title, title); 
    var result = _collection.UpdateOneAsync(filter, update).Result; 
} 
+0

thể trùng lặp của [MongoDB - Cập nhật một đối tượng trong lồng Mảng] (http://stackoverflow.com/questions/10522347/mongodb-update-an-object- in-lồng nhau-mảng) –

+0

@BlakesSeven đó không phải là aC# câu hỏi? –

+0

Nó vẫn là nguyên tắc tương tự. Phù hợp với phần tử mảng trong phần truy vấn và sử dụng toán tử '$' vị trí trong phần cập nhật. Tôi không chỉ ngẫu nhiên kéo nó ra khỏi túi. –

Trả lời

30

Đã cho tôi một thời gian để con số này ra vì nó không xuất hiện để được đề cập trong một trong các tài liệu chính thức (hoặc bất cứ nơi nào khác). Tuy nhiên, tôi đã tìm thấy this trên trình theo dõi vấn đề của họ, giải thích cách sử dụng toán tử vị trí $ bằng trình điều khiển C# 2.0.

này nên làm những gì bạn muốn:

public void UpdateItemTitle(string agendaId, string itemId, string title){ 
    var filter = Builders<TempAgenda>.Filter.Where(x => x.AgendaId == agendaId && x.Items.Any(i => i.Id == itemId)); 
    var update = Builders<TempAgenda>.Update.Set(x => x.Items[-1].Title, title); 
    var result = _collection.UpdateOneAsync(filter, update).Result; 
} 

ý rằng khoản Item.Single() của bạn đã được thay đổi để Item.Any() và chuyển đến định nghĩa bộ lọc.

[-1] hoặc .ElementAt(-1) dường như được xử lý đặc biệt (thực ra mọi thứ < 0) và sẽ được thay thế bằng toán tử vị trí $.

trên sẽ được dịch sang truy vấn này:

db.Agenda.update({ AgendaId: 1, Items.Id: 1 }, { $set: { Items.$.Title: "hello" } }) 
+0

Xin lỗi vì quá chậm khi chấp nhận câu trả lời của bạn . Hoạt động rất tốt. Thật không may họ không hỗ trợ nhiều hơn một bộ chọn hoạt động: https://jira.mongodb.org/browse/SERVER-831 Có vẻ lạ với tôi, vì điều này có thể được sử dụng để làm cho một sự cô lập tốt hơn của bản cập nhật cần phải được thực hiện. –

+0

Cảm ơn Søren. Tôi phải nói rằng tôi không phải là fan của cú pháp mà họ đã chọn mặc dù nó có nghĩa là bạn không thể sử dụng IEnumerable hoặc ICollection và buộc bạn sử dụng IList hoặc một mảng đơn giản – Buvy

+0

@Buvy Bạn sẽ có thể sử dụng Phương pháp mở rộng LINQ 'ElementAt (-1)' là tốt. –

1

Cảm ơn, này là hữu ích. Tôi có một bổ sung mặc dù, tôi đã sử dụng ở trên cho mảng, đẩy vào một mảng lồng nhau và kéo từ một. Vấn đề tôi đã tìm thấy là nếu tôi có một mảng int (Vì vậy, không phải là một đối tượng, chỉ là một mảng int đơn giản) mà PullFilter đã không thực sự làm việc - "Không thể xác định thông tin serialization" mà là lạ vì nó chỉ là một mảng của ints. Những gì tôi đã kết thúc là làm cho nó trở thành một mảng các đối tượng chỉ với một tham số int, và tất cả bắt đầu hoạt động. Có thể là một lỗi, hoặc có lẽ sự thiếu hiểu biết của tôi. Dù sao, như tôi đã đấu tranh để tìm thông tin về kéo và đẩy vào mảng đối tượng lồng nhau với trình điều khiển C# 2.0, tôi nghĩ rằng tôi nên đăng phát hiện của tôi ở đây, khi họ sử dụng cú pháp trên.

var filter = Builders<MessageDto>.Filter.Where(x => x._id == entity.ParentID && x.NestedArray.Any(i => i._id == entity._id)); 
var update = Builders<MessageDto>.Update.PullFilter(x => x.NestedArray.ElementAt(-1).User, Builders<User>.Filter.Eq(f => f.UserID, userID)); 
Collection<MessageDto>(currentUser).UpdateOneAsync(filter, update); 

Và cũng:

var filter = Builders<MessageDto>.Filter.Where(x => x._id == entity.ParentID && x.NestedArray.Any(i => i._id == entity._id)); 
var update = Builders<MessageDto>.Update.Push(x => x.NestedArray.ElementAt(-1).Users, new User { UserID = userID }); 
Collection<MessageDto>(currentUser).UpdateOneAsync(filter, update); 
Các vấn đề liên quan