[英]Upserting in Mongo DB and the Id problem
使用官方C#驅動程序向mongo db上傳時遇到問題。
public abstract class AggregateRoot
{
/// <summary>
/// All mongoDb documents must have an id, we specify it here
/// </summary>
protected AggregateRoot()
{
Id = ObjectId.GenerateNewId();
}
[BsonId]
public ObjectId Id { get; set; }
}
我的實體已經擁有了id-s但我必須創建mongo特定的ID才能工作,因為集合中的所有文檔都應該有一個。 現在我在我的系統中收到一個新的實體,生成一個新的Mongo Id,我得到的mongo不能改變文件舊異常的_id 。 有一些解決方法嗎?
讓我來描述一下設計。 將作為文檔存儲的所有實體都繼承自AggregateRoot,其中包含id生成。 每個子文檔都自動生成了id,我對此沒有任何問題。 引入AggregateRoot中的id是為了在從MongoCollection到List檢索數據時糾正問題,並且引入了生成,因此id-s不同。 現在我們可以移動id生成來保存方法,因為更新的新實體有一個新的id生成。 但這意味着團隊中的每個開發人員都不能忘記在存儲庫中生成id-s,這是有風險的。 如果可能的話,忽略id而不是從mongo映射會更好,而根本就沒有AggregateRoot類
我遇到過類似的問題。 我想使用官方C#驅動程序來插入文檔。 我有一個這樣的課:
public class MyClass
{
public ObjectId Id { get; set; }
public int Field1 { get; set; }
public string Field2 { get; set; }
}
在控制台我會寫: db.collection.update({Field1: 3},{Field1: 3, Field2: "value"})
,它會工作。 在C#中我寫道:
collection.Update(Query.EQ("Field1", 3),
Update.Replace(new MyClass { Field1 = 3, Field2 = "value" }),
UpdateFlags.Upsert);
它不起作用! 因為驅動程序在update語句中包含空id,當我使用不同的Field1異常值插入第二個文檔時,會拋出E11000 duplicate key error index
(在這種情況下,Mongo嘗試插入一個已經存在於db中的_id文檔)。
當我自己生成_id(比如主題啟動器)時,我在遇到具有現有值Field1的對象時遇到了同樣的異常( mongo cannot change _id of a document
)。
解決方案是按屬性[BsonIgnoreIfDefault]
標記Id屬性(而不是初始化它)。 在這種情況下,驅動程序在update語句中省略_id字段,MongoDb在必要時生成Id。
看起來您可能會顯式設置插入和更新的Id
值。 這對於插入很好,所有新對象都需要_id
值,但是對於更新,在創建現有文檔后,不允許更改現有文檔的_id
值。
盡量不要設置Id
值。 如果在插入之前未指定值,則驅動程序使用內置的IdGenerator
類生成新的_id值,因此如果它是ObjectId類型,則它將使用ObjectIdGenerator
。 然后你的插入和更新工作正常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.