I have a blog and a comment schema. In the comment schema the blog Id is being referenced. Now I have a function that lists all the blogs when the index page loads and it gets it by doing Blog.findById(id).populate('user','username'). I want to also be able to populate all the comments this blog has but comments are not referenced inside the blog schema. I know that in the exec callback I can then do comment.find(blogid) but that is just tedious. I want to know if there is a better way of doing this. Thanks
If you are not referencing the comments in the blog schema, there is no way you can populate it. populate is only used for fields present in the document. As you said, getting all the comments with the blog _id using comment.find in the callback of Blog.findById for the schema you are using is the way to go.
To make this process more efficient keep an index (documentation) on the blogid field in the Comment collection. This will back the comment.find({blogid:<some blogid>}) more efficient as indexed queries are super fast.
Related
I'm creating a discussion system using Parse.com
In my [simplified] system, there are Posts, Categorys, and Comments.
As you probably imagined, Posts can belong to one or more Categorys and can have multiple Comments.
However, often users will want to see all the Posts in a Category. If I set up my database like this
Post (name, content, categories)
Category(name)
I am worried that querying for all the Posts in a Category will be very ineffeficient (since it will have to check the categories field of every Post.
However, if I design the database like
Post (name, content)
Category(name, posts)
it will be inefficient for me to query what Categorys a Post belongs to since it will have to search all the Posts arrays in the all the Categorys.
I'm sure this must be a common Database design dilemma but I am still new at this. What is the best way to approach and solve this problem?
What you're looking for is a bi-directional, many-to-many relationship between Post and Category. With Parse, there are at least three approaches you can take.
You can add a column as a PFRelation to the Post table. You can ask a Post for its categories relation, create a query from that and run it. Inversely, if you have a category you can create a Post query with a where clause on the categories key. PFRelations are good if you will have big collections.
If you think better as a relational model, just create a "join" table called CategoryPosts. It would have two pointer columns, one for the Post and another for the Category. This is also very efficient.
Lastly, you could add an array column to either class. Since all of the results are loaded at once, this works best for smaller collections.
These options are described in a little more detail in the Parse Relations Documentation.
On the sails documentation here it shows modeling one to many associations with what looks like high level referencing.
Lets say I want to use mongo to make a post that has a lot of comments on it. I will take the post as the document and in it I will embed all the comments in one attribute.
If I did it like the documentation, would the mongo adapter automatically, create a document with the comments embedded? or would it do something relational and reference the comments?
If it doesn't embed, how would I go about putting the embedded comments in my model?
Thanks
Mongo doesn't provide associations on its own. Sails uses Waterline for ORM.
You need to create your Comment object yourself and just add its id to the appropriate attribute in the Post instance(which should be a collection), using post.comments.add(comment.id).
Removal is similar, just call post.comments.remove(comment.id)
Note that at some point you might not like to have thousands of commentids being fetched every time you retrieve a Post (or worse, thousands of Comment documents if you populate and fetch). This, of course, is only a concern if you're expecting thousands of comments per post in the first place.
Oh, and don't forget to save your document to finalize the changes.
Is there a way in Meteor/MongoDB to do a find to get the collection an document's _id exists in?
What I am trying to accomplish is to create a generic Comments framework for my app, where comments can be applied to several different document types that are saved in multiple Mongo collections. For instance, comments can be applied to Pages as well as Comments. What I need to do is save the comment, then modify the parent document. I can pass in the _id of the parent, but without strong typing I can't figure out if this is a Page or a Comment (or any other "commentable" type I might come up with.
One solution, I think, would be to store the "parent"'s ID in the comment, but I wanted to try to save an array of comments in the parent instead.
I have a class Post which has a list of embedded document called "comments"
Here all i want to do is to retrieve latest comments for all the posts user posted.
How can i achieve that? My current code, i just loop though the 'Post' class for that user and manually collect "comment".
But I also want this to be sorted by recently added, so have sort function to loop over manually collected comments and re-sort.
This seems like very inefficient, so asking for advise. Thanks!
Firstly if you $push onto the list with an update then you will keep the comments in order.
You can use the $slice operator to return the last x comments eg:
Post.objects(id=xxx).fields(slice__comments=-5)
However, the schema may not be efficient especially if you keep growing the number of comments, or comments can be unpublished. In that case you may want to split comments out into their own Document Model and link the comments to the Post by id. This would be two round trips to the database but offers more flexibility - eg. you could filter on date and published.
if I got a collection for storing Articles with it's Comments embedded, when retriving data from db, I will get a Article object with a completely Comment list, support there are a lot of comments, so this could be a problem of loading efficience, how can I handler this by paging Comments? do I have to use a seperate collection for Comments? or what else? thanx in advance.
You looking for the $slice operator.
To retrieve comments by paging you need code like this:
db.articles.find({}, {comments:{$slice: [20, 10]}}) // skip 20, limit 10
This operation will return articles with only sliced comments. )
The biggest question is:
Are your users more interested in comments or in context viewed?
Highly:
Put comments in separate documents, and load them first!
Then send "secondary" content via AJAX.
Moderately:
Use Andrew's solution. (And do not forget that you can also omit fields in queries)
Hardly:
Put comments in separate documents, and load them last (via AJAX).
(Also using AJAX can give you nice feature of expanding loaded comments via simple scrolling down)