title: How to improve query performance with operators like $nin, $in for Mongodb
body: <p>I have a reasonably large dataset of over 3 million documents that have tags similar to StackOverflow that uses tags for each question. The schema that I use for storing the tags is as follows:</p>
  
  <pre><code>{"id": 12345, "tags":["tag1", "tag2", "tag3"]}, {"id": 12346, "tags":["tag2", "tag3"]}
  </code></pre>
  
  <p>I have a multi-key index created on tags field. When I am performing queries using $in or $nin operators to find the intersection, union of the tags, the performance is around 7 seconds on a server class machine. Is there anything that I can do to improve the speed of query search?</p>
  
  <p>EDIT 1: </p>
  
  <p>Here is the explain plan as requested. What I observed is that the queries returned much faster after I restarted my server and just ran just the mongodb server. The queries performed much faster(&lt; 50ms). I suspect the indexes were not cached in memory, although I had ample unused ram available and my index (800MB) could easily fit in memory.</p>
  
  <blockquote>
    <p>db.tagsCollection.find( { "tags" : { $in : ['tag1', 'tag2'], $nin : ['tag4', '
    tag5', 'tag6', 'tag7'] } } ).explain();
    {
            "cursor" : "BtreeCursor tags_1 multi",
            "nscanned" : 6145193,
            "nscannedObjects" : 6145192,
            "n" : 969386,
            "millis" : 19640,
            "nYields" : 0,
            "nChunkSkips" : 0,
            "isMultiKey" : true,
            "indexOnly" : false,
            "indexBounds" : {
                    "tags" : [
                            [
                                    "tag1",
                                    "tag1"
                            ],
                            [
                                    "tag2",
                                    "tag2"
                            ]
                    ]
            }
    }</p>
  </blockquote>
  
  <p>Note</p>