title: How to deal with Many-to-Many relations in MongoDB when Embedding is not the answer?
body: <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>