I suggest the following structure:
Album { Id, UserId, Title, Category, Tags (list of tag names for fast access and for searching), Ratings (user ids, use $addToSet), Likes (user ids, use $addToSet), ViewsCount, (probably just integer value,) RatingsCount (use $inc to increment this field once someone vote for album), CommentsCount (use $inc everytime when someone post comment), LikesCount (use $inc everytime when someone click 'Like it') } Comment { Id, AlbumId, Text, CreatedDate, Ratings, RatingsCount, Replies { (collection of comment replies) Text, CreatedDate, Ratings, RatingsCount } } Tag { Id, TagName, AlbumsCount (use $inc: 1 when new album created with this tag and $inc:-1 - once deleted) }
I moved the comments to separate collections (instead of inserting them into the album), because so far it is difficult to update documents with more than one nesting level in mongodb.
Now requests:
1) Get the 10 most popular albums (title, thumbnail, views, comments, author and date) with paging. If the user clicks the "Next" button, add the 10 most popular albums, etc.
db.albums.find().skip(0).limit(10).sort( { RatingsCount: -1 } );
2) Get the 10 most popular paging albums.
db.albums.find().skip(0).limit(10).sort( { ViewsCount: -1 } );
3) Get the 10 most talked about paging albums.
db.albums.find().skip(0).limit(10).sort( { CommentsCount: -1 } );
4) Get a list of recently created paging albums, but up to 100 albums
db.albums.find().skip(0).limit(100).sort( { CreatedDate: -1 } );
5) Get all the albums of this user (name, thumbnail, views, likes, author and date)
db.albums.find({UserId: someUserId})
6) Get detailed information about a particular album and show only 10 paging comments. Next, the next 10 comments will be loaded and so on.
album = db.albums.find({_id: someAlbumId}); comments = db.comments.find({AlbumId: someAlbumId }).skip(0) .limit(10).sort( { RatingsCount: -1 ,CreateDate: -1 } );
7) Get a list of related albums. Communication will be via album tags or album name
Please clarify
8) Keyword search will search for the name or field of the album tag.
db.albums.find( { $or : [ { Title : searchKey } , { Tags : searchKey } ] } )
Note. You probably need to store the tag twice: lowercase for search and as shown for display
9) When someone clicks on a tag, get a list of all albums with this tag
db.albums.find( {Tags : { $in: [tagName1, tagName2]}} ] } )
Note. Using $ in oprator, you can search for multiple tag names.
10) When someone clicks a category link, get a list of 10 category albums
db.albums.find({Category: val }).skip(0).limit(10).sort( { CreatedDate: -1 } );
11) Get comments sorted by rating, date, etc.
db.comments.skip(0).limit(10).sort( { RatingsCount: -1 } );
12) Is it possible to control the order in which new records in a document are managed?
Please clarify
I think that now you see that you can move your relational database to MongoDB and assume that your application will grow very quickly with mongodb and above schema;).
I hope for this help.
PS: If sql 2005, than I assume, are you using any .net language?