sql >> データベース >  >> NoSQL >> MongoDB

ブログ用のmongodbスキーマ設計

    Article {
      "_id" : "A",
      "title" : "Hello World",
      "user_id" : 12345,
      "text" : 'My test article',
    
      "comments" : [
        { 'text' : 'blah', 'user_id' : 654321, 'votes' : [987654]},
        { 'text' : 'foo', 'user_id' : 987654, 'votes' : [12345, 654321] },
        ...
      ]
    }
    

    ここでの基本的な前提は、Commentsをネストしたことです。 Articleの内部 。 Votes Commentsにのみ適用されます 、したがって、各Commentの配列として保存されています 。この場合、user_idを保存しました。より多くの情報(time_createdなど)を保存したい場合は、オブジェクトの配列に投票できます:

    ... 'votes' : [ { user_id : 987654, ts : 78946513 } ] ...
    

    クエリを効率的に実行する方法:

    db.articles.find( { _id : 'A' } )
    

    これにより、1つのクエリですべてが取得されます。コメントごとの開票をカウントするには、クライアント側のロジックを実行する必要があるかもしれませんが、これは非常に簡単です。

    db.articles.ensureIndex( { "comments.user_id" : 1 } )
    db.articles.find( { "comments.user_id" : 987654 } ) // returns all document fields
    

    インデックスを使用すると、ドキュメント内のコメントを効率的に検索できます。

    現在、サブ配列から一致のみを抽出する方法はありません。このクエリは、実際には、そのユーザーによるコメントを含むすべての記事を返します。これがデータ量が多すぎる可能性がある場合は、トリミングを行うことができます。

    db.articles.find( { "comments.user_id" : 987654 }, { "title" : 1, "comments.user_id" : 1 })
    
    db.articles.ensureIndex( { "comments.votes" : 1 } )
    db.articles.find( { "comments.votes" : 987654 } )
    

    繰り返しになりますが、これにより、コメントだけでなく、すべての記事が返されます。

    ここではトレードオフが必要です。記事を返すと、データが多すぎるように見える場合があります。しかし、クエリ#3を実行するときに、ユーザーに何を表示する予定ですか?

    「私が投票したコメント」のリストを取得する コメント自体がなければ、それほど有用ではありません。もちろん、コメントは記事自体(または少なくともタイトルだけ)なしではあまり役に立ちません。

    ほとんどの場合、クエリ#3はVotesからの結合に発展します CommentsArticles 。その場合は、最初に記事を元に戻してみませんか?




    1. ReactiveMongoでPlay!2.5をセットアップする方法

    2. MongoDBでドキュメントのサイズを取得する2つの方法

    3. アイテムをMongodbコレクション配列にプッシュする

    4. MongoDBで条件付きのネストされたドキュメントを削除します