Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to deal with Many-to-Many relations in MongoDB when Embedding is not the answer?
    primarykey
    data
    text
    <p>Here's the deal. Let's suppose we have the following data schema in MongoDB:</p> <ul> <li><code>items</code>: a collection with large documents that hold some data (it's absolutely irrelevant what it actually is).</li> <li><code>item_groups</code>: a collection with documents that contain a list of <code>items._id</code> called <code>item_groups.items</code> plus some extra data.</li> </ul> <p>So, these two are tied together with a Many-to-Many relationship. But there's one tricky thing: for a certain reason I cannot store items within item groups, so -- just as the title says -- embedding is not the answer.</p> <p>The query I'm really worried about is intended to find some particular groups that contain some particular items (i.e. I've got a set of criteria for each collection). In fact it also has to say how much items within each found group fitted the criteria (no items means group is not found).</p> <p>The only viable solution I came up with this far is to use a Map/Reduce approach with a dummy reduce function:</p> <pre><code>function map () { // imagine that item_criteria came from the scope. // it's a mongodb query object. item_criteria._id = {$in: this.items}; var group_size = db.items.count(item_criteria); // this group holds no relevant items, skip it if (group_size == 0) return; var key = this._id.str; var value = {size: group_size, ...}; emit(key, value); } function reduce (key, values) { // since the map function emits each group just once, // values will always be a list with length=1 return values[0]; } db.runCommand({ mapreduce: item_groups, map: map, reduce: reduce, query: item_groups_criteria, scope: {item_criteria: item_criteria}, }); </code></pre> <p>The problem line is:</p> <pre><code>item_criteria._id = {$in: this.items}; </code></pre> <p>What if this.items.length == 5000 or even more? My RDBMS background cries out loud:</p> <pre><code>SELECT ... FROM ... WHERE whatever_id IN (over 9000 comma-separated IDs) </code></pre> <p><strong>is definitely not a good way to go</strong>.</p> <p>Thank you sooo much for your time, guys!</p> <p>I hope the best answer will be something like "you're stupid, stop thinking in RDBMS style, use <strong>$its_a_kind_of_magicSphere</strong> from the latest release of MongoDB" :)</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload