Best way to model simple blog coming from SQL to NOSQL - node.js

When using a SQL database for creating a basic blog I would have an author table, categories table and the posts table. I would then use joins on the blog page to get the author name and category i.e.: in the posts table when creating a post the user ID and the category ID would be stored.
If the user loves dogs and they write 100 posts about dogs under the category, 'dogs' and one day the website owner decides to change that category name to 'canine', no big deal. Because of the database design, all 100 blog posts will show category name 'canine' now. Great!
I however want to set this up with Mongo and have read different views on this. Some say you should store the category _id in the posts table and use references, others say that is defeating the purpose of using a nosql database and you should just store the category name in the posts collection. Personally, I would love to do that but what happens when you have 10000000 blog posts with the same category name and then the category name in the category collection gets changed?
Does that mean that when the category name is changed, your code should also update every single blog post with that category, and how since all that is stored is the category name and not _id ?

Related

Fetching 'related documents' from mongodb

So I have a very specific question about the optimum way of storing & then fetching data from a MongoDB database and ill try my best to explain the use case:
I have a content publishing platform that I've built. On this platform, a user can say, write a story, and the story gets saved as a document in the 'stories' collection in the database in a structure such as this:
{
_id : s_12345,
title : This is a story,
...
}
now on the same platform, let's say, another user writes a 'news article', which gets saved as a document in a separate 'news' collection. But now, the interesting thing is, while writing this news article, the user could 'tag' a story of their choice so that this news article would show up in a 'related content' section when some user on the platform is viewing that particular story. So the data structure of this news article could be:
{
_id : n_12345,
title : This is a news article,
related_to_tag : s_12345 //id of the story
...
}
Now from my understanding as of now, there are 2 ways of doing this:
OPTION 1: when a user tries to view this story (s_12345), we make a get request to the server, fetch this particular story document from the 'stories' collection in the database, then cycle through ALL the documents in the 'news' collection and pick up all the documents that have the related_to_tag === s_12345, and then return the story document + all these related news documents to the client. However this operation seems pretty expensive to me, especially if I have, let's say, 10,000 news articles in the news collection.
OPTION 2: At the time of posting the 'news article' to the database, I also find the story (s_123456) in the stories collection, and write a reference to the news article in this story document itself, like so:
{
_id : s_12345,
title : This is a story,
related_content : n_12345
...
}
The second option seems better to me. Because then, when a user tries to get the story, I already know all the other news articles that are related to it, and simply have to run a mongoose populate function to populate these news articles. but it brings up other complications such as:
what happens when the author of the news article deletes it? that means that I will have to find the story document (s_12345), and delete the related_content reference (n_12345) as well.
Or maybe I could run a weekly cron-job that does this sort of cleanup.
Also what happens if, while I am doing this double write operation (write the news article to database + write a reference to the news article to the story document), the second operation fails for whatever reason. that would create data inconsistency.
Anyway, this is a question that I have been struggling with for quite some time now, hope I have explained my use case clearly.
Awaiting your responses!
Abrar

Nodejs Express multi category route schema

I list the articles under the category. but there are more than one subcategory. I want to write these together in connection. I also want the page number in the form of /page/2. What kind of schema should I use here.
This is the current route. But isn't work
([a-z0-9-_/]+/)?:slug([0-9a-z-_]+)(/page/:page([0-9]+))?$
Link structure
category/[category]/[sub]/[sub-sub]/page/[number]
Sample Link
category/language/mobile/swift/page/2
And I want the last subcategory name. (swift)

Many to Many relationship in Access Web App

I need to do a many to many relationship in my first Access 2013 web app.
I have a Parents table and a Students table. Each student can have two parents and each parent can have more than one student in the school.
Thinking like a seasoned Access desktop developer I took the usual route of creating a parents_students table to link the other two then hit a wall. How do I make the view show the relationship?
I found this topic: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/ccda03e3-a57b-4128-be72-f469c8ec30af/access-2013-web-app-handling-many-to-many-relationships?forum=accessdev
When I tried it, it is not doing what I want, or I am doing something wrong.
Seems like a very fundamental thing to be able to do.
Got an answer over at the MSDN forums. Link Here
Create a Parents_Students table with three fields
ID: AutoNumber
Student: Lookup the name field in the student table
Parent: lookup the name field in the parent table
To the Students View, add a SubView and add a tab called Parents. In the Data parameters set the Data Source to the Parents_Students table and the related field to Student.
Repeat the same procedure on the Parents View but use parent as the Related Field.

Node.js + Mongoose: Find data and get other data for each

I have two models Users and News. On the page which is written with Express framework are published news and under the news are comments. Inside News model is subdocument with comments which contains two fields - user (subfields:) { name, objectid } and comment. Because in addition to comment there is user's name, I would like to add some additional informations about it (like number of comments, link to website, ...).
And this is my question: How to get data of user (from Users model) for each comment from subdocument (from News model)?
Add a populate call to your find query to pull in the user details. I'm not quite clear on your schema, but something like:
News.find().populate('comments.userId').exec(...);
This relies on your schema defining userId as an ObjectId ref to Users.

CouchDB view collation, join on one key, search on other values

Looking at the example described in Couch DB Joins.
It discusses view collation and how you can have one document for your blog posts, and then each comment is a separate document in CouchDB. So for example, I could have "My Post" and 5 comments associated with "My Post" for a total of 6 documents. In their example, "myslug" is stored both in the post document, and each comment document, so that when I search CouchDB with the key "myslug" it returns all the documents.
Here's the problem/question. Let's say I want to search on the author in the comments and a post that also has a category of "news". How would this work exactly?
So for example:
function(doc) {
if (doc.type == "post") {
emit([doc._id, 0], doc);
} else if (doc.type == "comment") {
emit([doc.post, 1], doc);
}
}
That will load my blog post and comments based on this: ?startkey=["myslug"]
However, I want to do this, grab the comments by author bob, and the post that has the category news. For this example, bob has written three comments to the blog post with the category news. It seems as if CouchDB only allows me search on keys that exist in both documents, and not search on a key in one document, and a key in another that are "joined" together with the map function.
In other words, if post and comments are joined by a slug, how do I search on one field in one document and another field in another document that are joined by the id aka. slug?
In SQL it would be something like this:
SELECT * FROM comments JOIN doc.id ON doc.post WHERE author = bob AND category = news
I've been investigating couchdb for about a week so I'm hardly qualified to answer your question, but I think I've come to the conclusion it can't be done. View results need to be tied to one and only one document so the view can be updated. You are going to have to denormalize, at least if you don't want to do a grunt search. If anyone's come up with a clever way to do this I'd really like to know.
There are several ways that you can approximate a SQL join on CouchDB. I've just asked a similar question here: Why is CouchDB's reduce_limit enabled by default? (Is it better to approximate SQL JOINS in MapReduce views or List views?)
You can use MapReduce (not a good option)
You can use lists (This will iterate over a result set before emitting results, meaning you can 'combine' documents in a number of creative ways)
You can also apparently use 'collation', though I haven't figured this out yet (seems like I always get a count and can only use the feature with Reduce - if I'm on the right track)

Resources