2

I have an mongo object like this:

{
    "_id" : ObjectId("4fa291baf5de89b89cb03f4e"),
    "examples" : [
        "!@3123123123", "23423fd34", "23423we4234"
    ]
}

I need to select all objects that have >= 3 examples. What is the right way to do this?

Thanks.

Benjamin Harel
  • 2,906
  • 3
  • 24
  • 32

2 Answers2

3

Maintain a dedicated counter variable as part of the document and use this one for performing a related query.

  • That's what I don't wont to do :-) – Benjamin Harel May 06 '12 at 13:05
  • Benjamin, it's the best way though. Map reduce is overkill for this. – Derick May 06 '12 at 13:19
  • +1 Using a counter is the correct solution for MongoDB. As Derick stated you could use map/reduce, but it's very slow and limited to collections of a maximum of 20,000 objects. – theTRON May 06 '12 at 19:20
  • @theTRON any references to 20000 objects limit? – rubish May 06 '12 at 19:33
  • Alas, I cannot find a doc reference to this now. I know that I have hit this limit in the past when I was benchmarking map/reduce on collections greater than 100,000 objects. However I believe these limits have been resolved by the recent MongoDB aggregation framework. – theTRON May 06 '12 at 19:44
1

There are different ways to do that. If your collection is not huge, only a couple thousand entries, then you can do it like this:

User.all.select {|user| !user['examples'].nil? and user['examples'].count >= 3}

That loads ALL entries from the collection into memory and does the selection with a Ruby native feature. You should not do this if you have 10 million entries in the collection.

Since MongoDB 2.2+ you can do this:

User.collection.find({'examples.2' => {'$exists' => true}})

That will return all users which have at least 3 elements in the 'example' subcollection. The counting starts with 0, the position of the element in the subcollection. We use this feature at VersionEye to identify users who don't follow anything.

Robert Reiz
  • 4,243
  • 2
  • 30
  • 43
  • By the way. The code snippet I posted is from Ruby. You might change the syntax a bit for other languages. But in general it works fine. – Robert Reiz Jan 03 '14 at 10:19