2017-12-05 22 views
0

私はMongoDBでとても新しいです(1日の学習に費やすだけです)。私は解決するのが比較的簡単な問題を抱えています。私はこの機会を利用して、この人気のあるnosqlデータベースについて学びます。MongoDB C#ドライバ2.0コレクションを更新して重複を無視します

public class Item 
{ 
    [BsonId] 
    public string ItemId { get; set; } 
    public string Name { get; set; } 
    public ICollection<Detail> Details { get; set; } 
} 

public class Detail 
{ 
    //[BsonId] 
    public int DetailId { get; set; } 
    public DateTime StartDate { get; set; } 
    public double Qty { get; set; } 
} 

は、私は詳細コレクションに複数のオブジェクト(詳細)を追加できるようにしたい:C#ので は、私は以下のクラスを持っています。しかし、私が持っているアイテムのいくつか(残りのAPIから来ている)はすでにデータベースに保存されており、重複を避けたいと思っています。 これまでのところ、私はそれを行うための2つの方法を考えることができますが、私はどちらかと本当に満足していない:

  1. はMongoDBのから(アイテムごと)保存されているすべての詳細を取得して、.NETで、私は をフィルタリングして見つけることができます新しい項目を追加し、それらをdbに追加します。このようにして、重複がないことを確信できます。しかしそれは理想的な解決策からは遠いです。

  2. [BsonId]属性をDetailIdに追加できます(この属性がないとこのソリューションは機能しません)。次にAddToSetEachを使用します。これはうまくいくと私の唯一の問題は、私がそれをかなり理解していないということです。つまり、新しいオブジェクトがデータベースにまだ存在しない場合は、 のオブジェクトのみを追加することになりますが、それはどのようにして知ることができますか?どのようにオブジェクトを比較するのですか?その比較プロセスを支配していますか?カスタム比較商品を提供できますか?また、同じDetailIdを持つ2つのオブジェクトを渡すと(実際のアプリケーションではこのようなことは起こりません)、BsonId属性は一意性を保証しません。

この問題の解決策はありますか?基本的には、別のコレクション(すでにdbに格納されているオブジェクトの一部(つまり最初のコレクション)が含まれていることがわかっています)を渡してすべての重複を無視して、Detailsコレクションを更新したいだけです。

答えて

0

AddToSetEachベースのバージョンは、正しくスケールする唯一のものだから確かに行く方法です。

しかし、アプリケーションの他の部分で実際に必要でない限り、DetailIdフィールド全体を削除することをお勧めします。遠くから判断すると、商品詳細のリストにある項目は、そのStartDateフィールド(プラスQty)に一意に識別されるように見えます。だからなぜあなたはその上にDetailIdが必要でしょうか?

DetailIdプロパティに[BsonId]属性を追加しても、Detail要素のコレクション内に一意性が保証されるわけではありません。一つの理由は、MongoDBはそれを単に行うことができないということです(this link参照)。 2番目の理由は、MongoDB C#ドライバがユニークなインデックスを作成しない、またはここで一意性を保証するために他の魔法を試行しないことです。おそらく理由#1のためです。 ;)すべての[BsonId]属性は、属性のプロパティを "_id"フィールドとしてシリアル化するようにドライバに指示します(逆シリアル化時には逆の方法で書き込みます)。 「どのようにMongoDBは、すでに存在するオブジェクトを知っているん」の話題で、documentationはかなり明確

されています:

値が文書である場合には、MongoDBのがあれば文書が 重複していると判断し配列内の既存のドキュメントは、追加する ドキュメントと正確に一致します。すなわち、既存の文書は全く同じフィールド を有し、値およびフィールドは同じ順序である。したがって、フィールドオーダー は重要であり、MongoDBが のサブセットのみをドキュメント内のフィールドと比較して、ドキュメントが既存の配列エレメントの複製である であるかどうかを判断することはできません。

また、カスタムの比較対象を指定するオプションはありません。

関連する問題