title: How do we optimize our mongo logging for analytics
body: <p>We log activity on our website using mongo, but now that our traffic has grown we're struggling to pull the reports we want. We hit timeouts. Each user session has it's own record which include the following attributes - </p>
  
  <pre><code>{
    channel: 'adwords',
    device: {
      type: 'mobile'
    },
    abTestArms: [
      test1_arm2,
      test3_arm4
    ],
    userEventCounters: {
      clickOnRedButton: 3,
      adjustPriceSlider: 4,
      clickOnBlueButton: 2,
      useSearchBox: 4
    }
  }
  </code></pre>
  
  <p>We run lots of AB tests and want to find how different versions effect user activity. So we might run queries like -</p>
  
  <pre><code>db.sessions.count({channel:'bing',device:'tablet',abTestArms:'test1_arm1','userEventCounters.useSearchBox':{$exists:true}})
  </code></pre>
  
  <p>Or </p>
  
  <p><code>db.sessions.count({channel:'bing',device:'tablet',abTestArms:'test1_arm1'})</code></p>
  
  <p>We used to use aggregation pipelines, but they started timing out, so now we're building the results bit by bit, but even like this we hit timeouts.</p>
  
  <p>We've tried various different indexes, so for example compound indexes like </p>
  
  <pre><code>{channel:1, device:1, abTestArms:1, userEventCounters:1}
  </code></pre>
  
  <p>The only thing we haven't tried is creating lots of compound indexes like </p>
  
  <pre><code>{channel:1, device:1, abTestArms:1, 'userEventCounters.hoverOverAd':1}
  </code></pre>
  
  <p>The issue with this, is that there's lots userEvents that we track, and we don't want 40+ compound indexes like this. Also we'd have to create new indexes whenever we track a new event.</p>
  
  <p>We currently keep about 3m sessions in our db, and the bigger count queries are normally in the 100k's. This can't be an uncommon thing to do, ideally I'd like to be able to do this stuff on the fly (as we used to when traffic levels were small). What am I missing?</p>