pythonmongodbtornado-motor

How to group by in Motor 1.1?


I'm using Motor async client for mongoDB in current project, and I'd like to use aggregation like group by for query. Docs contain short info about group, but no examples how.

Parameters:

  1. key: fields to group by (see above description)
  2. condition: specification of rows to be considered (as a find() query specification)
  3. initial: initial value of the aggregation counter object
  4. reduce: aggregation function as a JavaScript string

I don't know what exactly means initial parameter and reduce (as a javascript string?). Can you prodive an example?


Solution

  • Motor's group method takes the same parameters as PyMongo's. Adapting the PyMongo group example to Motor:

    from bson.code import Code
    from tornado import ioloop, gen
    from motor import MotorClient
    
    reducer = Code("""
                   function(obj, prev){
                     prev.count++;
                   }
                   """)
    
    db = MotorClient().test
    
    
    @gen.coroutine
    def example():
        yield db.things.remove({})
        yield db.things.insert_many([
            {'x': 1},
            {'x': 2},
            {'x': 2},
            {'x': 3},
        ])
    
        results = yield db.things.group(key={"x": 1}, condition={},
                                        initial={"count": 0}, reduce=reducer)
        for doc in results:
            print(doc)
    
    
    ioloop.IOLoop.current().run_sync(example)
    

    This prints:

    {'count': 1.0, 'x': 1.0}
    {'count': 2.0, 'x': 2.0}
    {'count': 1.0, 'x': 3.0}