1

次のドキュメント構造があるとしましょう。

class BlogPost
{
   [MongoIdentifier]
   public Guid Id{get;set;}
   public string Body{get;set;}
   ....
}

class Comment
{
   [MongoIdentifier]
   public Guid Id{get;set;}
   public string Body {get;set;}
}

複数のユーザーが同じ投稿にコメントを投稿する可能性があると仮定した場合、これらの間の関係をモデル化するための最良の方法は何でしょうか。

Postにコメントのコレクションがある場合、同時実行の問題が発生する可能性がありますね。

そして、コメントにFKのような属性を配置することは、あまりにも関係的であるように思われますか?

4

4 に答える 4

4

基本的に2つのオプションがあります:1。投稿ドキュメントにコメントを集約するか、2。投稿とコメントをドキュメントとしてモデル化します。

コメントを集約する場合は、a)競合状態を検出して楽観的な同時処理を実装できるように、投稿にリビジョン番号を実装するか、b)MongoDB修飾子を使用して新しいコメントを追加する必要があります。

var posts = mongo.GetCollection<Post>();
var crit = new { Id = postId };
var mod = new { Comments = M.Push(new Comment(...)) };

posts.Update(crit, mod, false, false);

findOne投稿とコメントを別々のドキュメントとしてモデル化する場合、同時実行の処理はおそらく簡単ですが、1つのコマンドで投稿とそのコメントをロードする機能が失われます。

私の意見では、(1)は、投稿を集約オブジェクトとしてモデル化するため、これまでで最も興味深いオプションです。これは、OOメガネをかけたときとまったく同じです:)。これは間違いなくドキュメント指向のアプローチですが、(2)はリレーショナルデータベースのフラットな構造に似ています。

于 2011-02-18T20:18:14.460 に答える
2

これは、標準的な NoSQL の例の 1 つです。これを行う標準的な方法は、Commentsをオブジェクトの配列として 内に格納することBlogPostです。

並行性の問題を回避するために、MongoDB にはいくつかのアトミック操作が用意されています。特に、「サブドキュメント」または「サブ配列」でうまく機能する更新修飾子がいくつかあります。

「このコメントを投稿に追加する」などの場合、通常$push、コメントを投稿に追加するコマンドを使用します。

「NoRM」ドライバーを使用しているようです。テストで証明されているように、アトミック コマンドをサポートしているようです。実際、彼らのテストは「このコメントをブログ投稿にプッシュする」を実行します。

于 2011-02-18T20:57:55.143 に答える
0

それらは、挿入時にMongoDBページでそれをモデル化する方法の例を示しています-投稿のプロパティとして公開されるコメントのコレクションが必要だと思います。特定のPostエンティティにコメントを追加すると、Commentエンティティを親のPostエンティティに結び付ける必要がなくなります。これは、質問するのが正しいので、RDBMSでは意味がありますが、NoSQLではあまり意味がありません。解決。

並行性に関する限り、Mongoがそれを処理することを信頼していない場合は、その上にアプリケーションを構築するべきではないという大きなヒントになるでしょう。

于 2011-02-18T19:26:16.777 に答える
0

同じ「投稿」に「コメント」を追加する 1000 の同時スレッドを生成するテスト アプリを作成しました。その結果、多くのコメントが失われます。

そのため、MongoDB は子コレクションを単一の値として扱い、デフォルトでは変更をマージしません。

投稿にコメント コレクションがある場合、2 人以上のユーザーがまったく同時にコメントを追加すると、同時実行の問題が発生します (可能性は低いですが、可能性はあります)。

では、投稿オブジェクト全体を更新せずに、post.comments コレクションにコメントを追加することは可能でしょうか?

于 2011-02-18T19:54:22.707 に答える