Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would you implement these queries efficiently in MongoDB?

Links have one or more tags, so at first it might seem natural to embed the tags:

link = { title: 'How would you implement these queries efficiently in MongoDB?'
         url: 'http://stackoverflow.com/questions/3720972'
         tags: ['ruby', 'mongodb', 'database-schema', 'database-design', 'nosql']}

How would these queries be implemented efficiently?

  • Get links that contain one or more given tags (for searching links with given tags)
  • Get a list of all tags without repetition (for search box auto-completion)
  • Get the most popular tags (to display top 10 tags or a tag cloud)

The idea to represent the link as above is based on the MongoNY presentation, slide 38.

like image 923
randomguy Avatar asked Sep 15 '10 19:09

randomguy


People also ask

What would be the best way to improve the performance of a MongoDB query where your query references particular field within a document?

Other ways to improve MongoDB performance after identifying your major query patterns include: Storing the results of frequent sub-queries on documents to reduce read load. Making sure that you have indices on any fields you regularly query against. Looking at your logs to identify slow queries, then check your indices.

What are some tips to improve the performance of NoSQL queries?

Add Appropriate Indexes NoSQL databases require indexes, just like their relational cousins. An index is built from a set of one or more fields to make querying fast. For example, you could index the country field in a user collection.

How is querying done in MongoDB?

The first is to use a logical AND conjunction to select documents in the collection matching all the conditions, or the logical OR to select documents matching at least one condition from the list. In MongoDB, the AND conjunction is implicit when using more than one field in the query filter document.


1 Answers

Get links that contain "value" tag:

db.col.find({tags: "value"});

Get links that contain "val1", "val2" tags:

db.col.find({tags: { $all : [ "val1", "val2" ] }});

Get list of all tags without repetition:

db.col.distinct("tags");

Get the most popular tags - this isn't something that can be queried on an existing db, what you need to do is add a popularity field update it whenever a query fetches the document, and then do a query with the sort field set to the popularity.

Update: proposed solution for popularity feature. Try adding the following collection, let's call it tags.

doc = { tag: String, pop: Integer }

now once you do a query you collect all the tags that were shown (these can be aggregated and done asynchronously) so let's say you end up with the following tags: "tag1", "tag2", "tag3".

You then call the update method and increment the pop field value:

db.tags.update({tag: { $in: ["tag1", "tag2", "tag3"] }}, { $inc: { pop: 1 }});
like image 157
Asaf Avatar answered Nov 09 '22 12:11

Asaf