Using sort() with an inner array length

1,215 views
Skip to first unread message

dpapathanasiou

unread,
Jul 5, 2011, 2:33:34 PM7/5/11
to mongodb-user
I have a collection of people documents which look like this:

{u'name': u'... FirstName LastName ...',u'clubs': [ ... list of
dicts ...], u'_id': ObjectId('... object id value ...')}

I'd like to be able to query the most active people based on the
number of the clubs they belong to. Ideally, I'd like to use sort,
like this:

db.people.find().sort('clubs.length', -1).limit(10)

but instead of getting the top ten people by the number of clubs, that
query ignores the length property of the inner clubs array, and just
returns the first 10 docs in the collection, regardless of the clubs
length.

I have gotten this to work by using a map reduce structure instead,
but it seems sort() would be better and simpler for this type of
query.

The sort documentation (http://www.mongodb.org/display/DOCS/Advanced
+Queries#AdvancedQueries-{{sort%28%29}}) makes no mention of how to do
it, so is there some undocumented syntax to get it to work this way?

Bernie Hackett

unread,
Jul 5, 2011, 5:47:07 PM7/5/11
to mongodb-user
The easiest way to do what you want would probably be to add a count
field that tracks how many clubs a person belongs to:

>>> for entry in db.people.find().sort('count', -1).limit(10): print entry
...
{u'count': 2, u'clubs': [{u'name': u'Some Club'}, {u'name': u'Some
Other Club'}], u'_id': ObjectId('4e138599fba52201d3000000'), u'name':
u'Bill Smith'}
{u'count': 1, u'clubs': [{u'name': u'Some Club'}], u'_id':
ObjectId('4e1385acfba52201d3000001'), u'name': u'John Doe'}


On Jul 5, 11:33 am, dpapathanasiou <denis.papathanas...@gmail.com>
wrote:

dpapathanasiou

unread,
Jul 5, 2011, 7:26:11 PM7/5/11
to mongodb-user
On Jul 5, 5:47 pm, Bernie Hackett <ber...@10gen.com> wrote:
> The easiest way to do what you want would probably be to add a count
> field that tracks how many clubs a person belongs to:
>
> >>> for entry in db.people.find().sort('count', -1).limit(10): print entry
>
> ...
> {u'count': 2, u'clubs': [{u'name': u'Some Club'}, {u'name': u'Some
> Other Club'}], u'_id': ObjectId('4e138599fba52201d3000000'), u'name':
> u'Bill Smith'}

If that's the only way to do it using sort(), I'd rather stick to the
map reduce solution, and not have to worry about updating the count
attribute when the list of clubs changes.

Thanks for your reply.
Reply all
Reply to author
Forward
0 new messages