A
A
Andrey Khokhlov2017-09-04 05:48:20
MongoDB
Andrey Khokhlov, 2017-09-04 05:48:20

How to properly make a tag cloud with MongoDB?

The case is approximately the following:
1. There are n users, each can post documents
2. A user can add tags to each post
3. Users do not intersect with each other, each work with their own documents
Document (without extra fields):

{
  userId: ObjectId('...'),
  tags: ['foo', 'bar', 'baz']
}

4. The user enters the page with a list of his documents. Let's say the first 10 are displayed, and he has 100 of them, there is a paginator.
5. On the same page, a tag cloud with all tags is displayed (or a filter for posts by tags), without duplicates. That is, if we had two documents, one with the tags 'foo' and 'bar', the second with the tags 'bar' and 'baz', then 'foo, bar, baz' would be displayed.
What options do I see:
1. You can get all the documents from the database, collect an array of tags and throw out duplicates from it. Perhaps it is worth caching the result of such a selection (where?).
2. You can not save tags to a document, but store them in a separate collection
{
  userId: ObjectId('...'),
  tags: [ObjectId('...'), ObjectId('...')]
}

But it after all already MySQL will turn out.
How to solve such a problem correctly?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
P
Ptolemy_master, 2017-09-05
@andrhohlov

I would do so.
The page with the list of documents is loaded as usual, along with the list of tags is loaded, which is stored as a regular array of strings associated with the user profile, formed as described in your option number 1. (I don’t see the point of making a separate collection for simple lists, it’s always better to start with minimization entities - Occam's razor, yeah :)
When we load a page with a list, tags are loaded. All subsequent calls to other pages are made asynchronously, therefore, the tag cloud does not need to be loaded anymore.
I do not know what you are using on the client, I work closely with Angular, so I can only talk about it.
Technically, it would be done like this - the route for the list of documents is registered on the server, the profile with the list of tags is returned to the client. Angular routes contain page calls. In the case of the initial load, a request is made to page number 1 (as the resolver for this route), subsequent calls are simply asynchronous to fetching the corresponding page.
Addendum.
The author of the post asked an additional question. You asked when to update the list. The question is not so simple and obvious. Ideally, the tag cloud should be updated as soon as the user adds or changes existing tags. If you want to implement exactly this functionality, then you can do it through sockets (a new list of tags is sent to the client in the browser, it's not difficult really). Another option is to track on the server when the document is saved whether the list of tags has changed, and if so, send the updated list in the response and update it on the client. Also nothing is an option, in my opinion.

O
oh, 2017-09-04
well @AnneSmith

I haven’t gotten to Mongo yet, but I’ve worked enough with json, I wouldn’t make a separate collection of tags, because users don’t overlap,
google "merge arrays remove duplicates" for your programming language

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question