Albert Prats
Albert Prats

Reputation: 796

Get result from mongo aggregation using pymongo 3.0

I am using python to query a mongo collection and retrieve a value from it:

subquery = db.partsupp.aggregate([
    {"$match": {"r_name": region }},
        {"$group": {
            "_id" : 0,
            "minim": {"$min": "$supplycost"}
            }
        }
])

This query works just fine and it outputs:

[{'_id': 0, 'minim': 10}]

What I am trying to do now is to get the minim value from this aggregation.

Initially what I wanted was an 'if' to check if the query had any results, like this:

if len(subselect['result']) > 0 :
    minim = subquery['result'][0]['minim']
else: 
    return subselect

But doing this only gets me the following error:

Traceback (most recent call last):  
File "query2.py", line 195, in <module>  
pprint( list(query2('Catalonia', 1, 1)) )  
File "query2.py", line 72, in query2

if len(subquery['result']) > 0 :  
TypeError: 'CommandCursor' object is not subscriptable

It looks like the result from the subselect query is not iterable or something like that, how can I solve this?

I am using Python 3.4.3 and pymongo 3.0.1.

Upvotes: 3

Views: 9083

Answers (2)

anhlc
anhlc

Reputation: 14429

Pymongo 3.0.1 returns aggregation results as cursor, which means you can't access the result with subquery['result']. To disable cursor and force pymongo to return a document with {'result':{...}} instead of a cursor, use this:

subquery = db.partsupp.aggregate([
    {"$match": {"r_name": region }},
        {"$group": {
            "_id" : 0,
            "minim": {"$min": "$supplycost"}
            }
        }
], useCursor=False)

From pymongo 4.0, useCursor is no longer available, use list() to convert cursor to a list:

cursor = db.partsupp.aggregate([
    {"$match": {"r_name": region }},
        {"$group": {
            "_id" : 0,
            "minim": {"$min": "$supplycost"}
            }
        }
])
subquery['result'] = list(cursor)

Upvotes: 11

tonysepia
tonysepia

Reputation: 3500

Since useCursor is deprecated and will be removed in PyMongo 4.0, I suggest iterating over the results:

subquery = db.partsupp.aggregate([
    {"$match": {"r_name": region }},
        {"$group": {
            "_id" : 0,
            "minim": {"$min": "$supplycost"}
            }
        }
])
results = [doc for doc in subquery]

Upvotes: 1

Related Questions