How to request all attached documents

I start with MongoDb and nodejs (using mongoose).

I have a collection of Stories , each of which can have one or more tags , something like this:

{ title: "The red fox", content: "The red fox jumps away...", tags: [ { tagname: "fairytale", user: "pippo" }, { tagname: "funny", user: "pluto" }, { tagname: "fox", user: "paperino" } ] }, ... other stories 

Now I want to create a tag cloud .

This means requesting stories for all tags.

In a relational world (like MySQL) I will have a Stories table, a tag table and a Stories_Tags table (many-to-many). Then I will query a tag table or something like that.

Is there any way to do this? (I'm sure yes)

If so, is this a good practice? Or does this violate the nosql paradigm?

Can you imagine the best way for my circuit design?

+8
mongodb tags mongoose nosql many-to-many
source share
4 answers

You can use MR to accomplish this. In MR, you simply select tags and project them:

 var map = function(){ for(var i=0;i<this.tags.length;i++){ emit(this.tags[i].tagname, {count: 1}); } } 

And then your reduction will go through the released documents, basically summing up the number of times this tag was noticed.

If you are upgrading to the latest erratic 2.2, you can also use the aggregation structure. You must use the $ project and $ sum piplines aggregation structures to project tags from each message and then sum them to create a point-based tag cloud, allowing the text size of each tag to be based on summation.

If so, is this a good practice? Or does this violate the nosql paradigm?

This is a fairly standard problem in MongoDB, and you will not be able to avoid it. With a reusable structure, the inevitable need arises to fulfill some complex queries on it. Fortunately, in version 2.2 there is an aggregationm structure for saving.

As for the good or bad approach, it is pretty standard, so it is neither good nor bad.

With regard to improving the structure, you can pre-aggregate unique tags with their calculation in a separate collection. This will make it easier to create a real-time tag cloud.

Pre-aggregation is a form of creating another collection that you usually get from MR without the need for MR or aggregation structure. Usually this event is based on your application, so when a user creates a message or checks the message, he triggers a pre-aggregation event in the tag_count collection, which looks like this:

 { _id: {}, tagname: "", count: 1 } 

When the event fires, your application will scroll the tags in the mail, basically doing $ inc upserts like this:

 db.tag_count.update({tagname: 'whoop'}, {$inc: {count: 1}}, true); 

So now you will have a collection of tags with your score on your blog. From there, you go along the same route as MR, and simply request this collection by taking out your data. Of course, you will need to handle uninstall and update events, but you will get a general idea.

+2
source share

Here's how you do it using the aggregation structure (you need to use the just released 2.2).

 db.stories.aggregate( [ { "$unwind" : "$tags" }, { "$group" : { "_id" : "$tags.tagname", "total" : { "$sum" : 1 } } }, { "$sort" : { "total" : -1 } } ]) 

Your result will look like this:

 { "result" : [ { "_id" : "fairytale", "total" : 3 }, { "_id" : "funny", "total" : 2 }, { "_id" : "silly", "total" : 1 }, { "_id" : "fox", "total" : 1 } ], "ok" : 1 } 
+10
source share

Welcome to mongo

The best β€œschema” for your data would be something like this.

You create a collection called stories, each story will be a document in this collection. Then you can easily request your data using something like.

 db.stories.find({ "tags.tagname": "fairytale"}); // will find all documents that have fairytale as a tagname. 

UPDATE

 db.stories.find({ "tags.tagname": { $exists : true }}); // will find all documents that have a tagname. 

Pay attention to the dot notation in the search query, how you get into arrays / objects in mongo.

+1
source share

Well, there are different ways. And I think that there is no difference between your decision and this one .

You can also copy and paste your map_reduce method to display the tag hash.

0
source share

All Articles