2014-01-06 8 views
6

MongoおよびNoSQLデータベースを初めて使用しています。誰かがメテオでコレクションを1対多に参加してサイクリングする方法を説明できますか?メテオコレクションの1対多の関係(またはそれに相当するNoSQL Mongo)

たとえば、投稿とコメントの2つのコレクションがあります。それぞれのコメントにはpostIdがあり、各投稿には0個以上のコメントが含まれています。 Meteorのこの種の状況のベストプラクティスとなることに興味があります。具体的には、それぞれの投稿を繰り返し、ネストされたHandlebarsコールでコメントすることができます。以下の例のような何か:

{{#each post}} 
    {{title}} 
    {{content}} 
    {{#each comment}} 
    {{comment_text}} by {{author}} 
    {{/each}} 
{{/each}} 
+1

mongodbでの結合はサポートされていません。 mongodbの方法は、ポスト文書のコメントを埋め込むことになります。 http://education.mongodb.comには、オンラインコースがあります。mongodbの上にブログを構築します。 – Mzzl

答えて

14

標準のMongoDBのパラダイムは、流星のアプリケーションでは、各論理データセットに対して異なるコレクション(テーブル)を有するのパターンに固執することも珍しくありませんが、データを非正規化することであるが。実装するに

は、あなたは、単に2つのコレクションの間の関係を定義する必要があり、流星のwebappsに参加する:

var postId = Posts.insert({ 
    title: "A post", 
    content: "Some content..." 
}); 

Comments.insert({ 
    postId: postId, 
    author: "Someone", 
    text: "Some text..." 
}); 

非正規化は、あなたが以下のように行うことができ、2つのコレクションを公開することを忘れてはならないことを意味します

Meteor.publish("postById", function(postId){ 
    // publish the according post... 
    var postCursor = Posts.find(postId); 
    // ...and every comments associated 
    var commentsCursor = Comments.find({ 
    postId: postId 
    }); 
    // you can return multiple cursors from a single publication 
    return [postCursor, commentsCursor]; 
}); 

この刊行物は、投稿とそのコメント(post._id)をクライアントに送信します。 正しいクライアント側のルーティングに関連付けられている場合、URL(/posts/:_id)から取得した投稿IDを使用してこのパブリケーションを購読し、すべてのコメントとともに投稿を表示できます。

あなたのテンプレート擬似コードはOKですが、コレクションごとに異なるテンプレートを使用してリファクタリングします。

HTML

<template name="outer"> 
    {{!-- loop through each post, the child template will 
     be using the current post as data context --}} 
    {{#each posts}} 
     {{> post}} 
    {{/each}} 
</template> 

JS

Template.outer.helpers({ 
    posts: function(){ 
    return Posts.find(); 
    } 
}); 

HTML

<template name="post"> 
    <h3>{{title}}</h3> 
    <p>{{content}}</p> 
    {{!-- loop through each comment and render the associated template --}} 
    {{#each comments}} 
    {{> comment}} 
    {{/each}} 
</template> 

JS

Template.posts.helpers({ 
    comments: function(){ 
    // return every comment belonging to this particular post 
    // here this references the current data context which is 
    // the current post being iterated over 
    return Comments.find({ 
     postId: this._id 
    }); 
    } 
}); 

HTML

<template name="comment"> 
    <p>{{text}}</p> 
    <span>by {{author}}</span> 
</template> 
+0

この素晴らしい答えとテンプレートのリファクタリングに関するアドバイスをありがとう。 – JAMESSTONEco