user888750
user888750

Reputation:

MongoDB 2.4 Aggregate Error: yielded unknown object MotorAggregationCursor

THIS IS NOT A DUPLICATE QUESTION The other question pertains to Mongo 2.6, which does aggregate a lot different than Mongo 2.4. I've already read the other question, even addressed it in the closing paragraph of this question.

First Off, I'm very new to Mongo, and even newer to PyMongo. I'm working with an existing script and trying to debug why it won't run locally. The following query results in an error.

Query:

[{
  u'$match': {
    u'geocode.co_iso2': u'US',
    u'brand._id': UUID('xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')
  }
},
{
  u'$group': {
    u'_id': u'$brand._id',
    u'num': {u'$sum': 1}
  }
},
{
  u'$sort': {u'num': -1}
},
{
  u'$limit': 100000
}]

Code:

cursor = yield db[collection].aggregate(bsonQuery)
self.write(bson.json_util.dumps(cursor))

Error:

Exception: <class 'tornado.gen.BadYieldError'>:yielded unknown object MotorAggregationCursor(<motor.core._LatentCursor object at 0x10a897b50>)

I also want to note that this is Mongo 2.4 and PyMongo 2.8. I know some people with a similar error are told to store cursor without the yield and then do a while(yield...). Tried that, doesn't seem to be applicable to Mongo 2.4. It says the following:

Exception: <class 'pymongo.errors.OperationFailure'>:command SON([('aggregate', u'MyCollection'), ('pipeline', [{u'$match': {u'geocode.co_iso2': u'US', u'brand._id': UUID('xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')}}, {u'$group': {u'_id': u'$brand._id', u'num': {u'$sum': 1}}}, {u'$sort': {u'num': -1}}, {u'$limit': 100000}]), (u'cursor', {})]) on namespace mydatabase.$cmd failed: unrecognized field "cursor

Upvotes: 0

Views: 509

Answers (1)

Blakes Seven
Blakes Seven

Reputation: 50406

I actually meant to add this to it's cousin question since there is another reason MongoDB 2.4 can specifically throw this error.

Simply put "cursors" were not supported in MongoDB 2.4 for an aggregate result. This means you need to turn that option specifically "off", and thus it makes the .aggregate() an "async" method call itself and the returned result is now a document containing an enumarable array "results":

reply = yield collection.aggregate(pipeline,cursor=False)
for doc in reply['results']:
    print(doc)

So it's the cursor=False that is missing on the call to make it "async".

Upvotes: 1

Related Questions