2017-07-25 18 views
2
interface Nameable 
{ 
    string Name { get; set; } 
} 

class Parent : Nameable 
{ 
    public string Name { get; set; } 

    public List<Child> Children { get; set; } = new List<Child>(); 
} 

class Child 
{ 
    public string Name { get; set; } 

    public int Value { get; set; } 

    public string DataOne { get; set; } 

    public string DataTwo { get; set; } 

    public double DataThree { get; set; } 
} 



    static async void MainAsync(string[] args) 
    { 
     for (int i = 0; i < random.Next(10000, 50000); i++) 
     { 
      Parents.Add(CreateParent()); 
     } 

     Parents = Parents.GroupBy(g => g.Name).Select(grp => grp.First()).ToList(); 

     foreach (var parent in Parents) 
     { 
      await Insert<Parent>(parent); 
     } 

     // update objects randomly; 

     foreach (var parent in Parents) 
     { 
      for (int i = 0; i < random.Next(10, 30); i++) 
      { 
       int decision = random.Next(0, 2); 

       if (decision == 0 && parent.Children.Count > 0) 
       { 
        parent.Children.RemoveAt(random.Next(0, parent.Children.Count)); 
       } 
       else 
       { 
        var inner = CreateChild(); 
        if (!parent.Children.Any(io => io.Name == inner.Name)) 
        { 
         parent.Children.Add(inner); 
        } 

       } 

       await ReplaceOne<Parent>(parent); 
      }    
     } 
    } 

私は親のリストを持ち、それぞれに子要素のリストを含んでいます。これらの親が新しい子を削除または追加することによって更新された後に、これらの親を置き換えるためにc#Mongoドライバを使用する場合、コードがreplaceメソッドを呼び出すときに複製が存在しないにもかかわらず、Mongo側にChildの複製が作成されることがあります。Mongoはサブ文書の重複を引き起こします。c#

これは、Mongoのアトミックサブドキュメント構造とアイテムの更新/置換の仕方と関係していると思います。これが重複を作成しないようにする方法はありますか?原子の性質のために起こっていない場合、これを引き起こしているのは何ですか? 編集:

static async Task ReplaceOne<T>(T obj) 
     where T : Nameable 
    { 
     await database.GetCollection<T>(typeof(T).Name).ReplaceOneAsync(Builders<T>.Filter.Where(t => t.Name == obj.Name), obj); 
    } 

    static async Task Insert<T>(T obj) 
    { 
     await database.GetCollection<T>(typeof(T).Name).InsertOneAsync(obj); 
    } 

    static Parent CreateParent() 
    { 
     var innerObjects = new List<Child>(); 
     for (int i = 0; i > random.Next(1, 10); i++) 
     { 
      innerObjects.Add(CreateChild()); 
     } 

     return new Parent() 
     { 
      Name = RandomString(), 
      Children = innerObjects 
     }; 
    } 

    static Child CreateChild() 
    { 
     return new Child() 
     { 
      Name = RandomString(), 
      Value = RandomInt(), 
      DataOne = RandomString(), 
      DataTwo = RandomString(), 
      DataThree = RandomDouble() 
     }; 
    } 

が置き換え/挿入スニペットを追加しました、彼らは、DBに挿入するのmongo C#のドライバを使用しています。 CreateParentとCreateChildは、ランダムな関連データでオブジェクトを塗りつぶすだけです。

+0

を 'CreateParent'は、' CreateChild'は、 'Insert'と' ReplaceOne'方法は次のように何を求めますか? – dnickless

+0

親/子を作成するだけで、ランダムデータでChild/Parentクラスを埋めることができます。 mongoに挿入するMongoのC#ドライバを使って挿入し、置き換えて置き換えてください。明日の朝に編集を投稿することができます。 – Jack

答えて

1

あなたのRandomString()RandomInt()RandomDouble()の方法を推測しようとしましたが、データベースをクリーニングせずにプロジェクトを何度も実行しました。私は2つの "名前"のプロパティ(親と子の)に基づいて重複を検出できませんでした。

あなたの所見は何とか間違っていると思われます。あなたが実際にあなたが次のクエリを使用することができ、同じ親内で重複して子供持っているかどうかをチェックするために:

collection.aggregate(
{ 
    $unwind: "$Children" 
}, 
{ 
    $group: 
    { 
     _id: 
     { 
      "Name": "$Name", 
      "ChildName": "$Children.Name" 
     } 
     , "count": { $sum: 1 } 
    } 
}, 
{ 
    $match: 
    { 
     "count": { $ne: 1 } } 
    } 
) 
+0

私の集計をチェックして、そこには重複があったように見えるそうではなかった。ありがとう – Jack

関連する問題