2017-08-01 83 views
0

我有一個類似於以下用於存儲許可證的文檔。不必要的字段被刪除。在MongoDB中使用C#驅動程序2.4.4更新兩次嵌套文檔3.4.6

{ 
    "_id" : "1", 
    "company_name" : "stackOverflow", 
    "license_holders" : [ 
    { 
     "UID" : "AAA-BBB-CCC-DDD", 
     "software_version" : "1.2.3", 
     "licenses" : [ 
     { 
      "creation_date" : "03.03.17", 
      "is_valid" : true, 
      "license_id" : "l1" 
     }, 
     { 
      "creation_date" : "03.03.16", 
      "is_valid" : false, 
      "license_id" : "l2" 
     } 
     ] 
    }, 
    { 
     "UID" : "111-222-333-444", 
     "software_version" : "1.2.3", 
     "licenses" : [ 
     { 
      "creation_date" : "05.05.17", 
      "is_valid" : true, 
      "license_id" : "l3" 
     }, 
     { 
      "creation_date" : "05.05.16", 
      "is_valid" : false, 
      "license_id" : "l4" 
     } 
     ] 
    } 
    ] 
} 

我可以通過這個查詢更新的軟件版本與給定UID:

public async Task<Customer> UpdateLicenseHolderSoftwareVersion(string uid, string softwareVersion) { 
     var update = Builders<Customer>.Update.Set(c => c.LicenseHolders[-1].CurrentSoftwareVersion, softwareVersion); 
     Customer customer = await DMSLicenseCollection.FindOneAndUpdateAsync(c => c.LicenseHolders.Any(h => h.UID == uid), update); 
     return customer; 
    } 

我無法找到一個方法來更新許可證的"is_valid"場。我正在嘗試使用UIDLicenseId字段選擇正確的許可證。我嘗試了很多東西,但沒有成功。嵌入這麼多文檔是不好的做法?或者我缺少一種方法來更新和檢索數組內的幾層嵌套文檔。謝謝...

回答

0

我有幾條建議可以讓你的生活更輕鬆。

  • 我發現有用的是不將嵌套的文檔存儲爲列表,但詞典。這樣你可以很容易地找到你想要更新的子文檔。例如,UID和license_id可以是您的字典中的鍵,並且可以爲字段的其餘部分賦值。
  • 我不是一個非常喜歡在db中識別不是主鍵的東西。這裏您根據UID和license_id更新子文檔。我認爲這是不好的做法,並建議你改變這一點。
  • 對於內嵌大量嵌套文檔的大文檔,您需要適度地瞭解您的行程。更多嵌套文檔意味着更慢的查詢執行。我建議你測試你的應用程序並檢查你是否滿意速度。

解決方案爲您當前的問題:

public async Task ToggleLicesneIsValid(string UID, int licenseId) 
    { 
     var filter = Builders<Customer>.Filter.ElemMatch(x => x.licence_holders, i => i.UID == UID); 
     var customer = DMSLicenseCollection.Find(filter).FirstOrDefault(); 
     var item = customer.licence_holders.FirstOrDefault(x => x.UID == UID).licenses.FirstOrDefault(y => y.license_id == licenseId); 

     item.is_valid = !item.is_valid; 

     await DMSLicenseCollection.ReplaceOneAsync(o => o.mongoId == customer.mongoId, customer); 
    } 

此法切換真/假的「is_valid」但我建議你有2種獨立的方法(用於設置一個設定是真的,一個是假的) 。這樣代碼更具可讀性,您可以避免潛在的錯誤。

PS我在我的測試中將id命名爲mongoId,但將其更改爲您的喜好。

乾杯!

+0

感謝您的建議,特別是對於字典之一。根據mongoDB,UID和license_id字段保證是唯一的,但它們不是主鍵。我發現你的解決方案替代了整個文檔,而不是試圖自動更新字段。我試圖找到一種方法,只在可能的情況下替換許可證文件,而不是整個客戶文件。感謝你的回答 :) – qua11q7

相關問題