Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cursor operator in Aggregate function not working.. #2306

Closed
mithralaya opened this issue Sep 15, 2014 · 15 comments
Closed

Cursor operator in Aggregate function not working.. #2306

mithralaya opened this issue Sep 15, 2014 · 15 comments
Milestone

Comments

@mithralaya
Copy link

Hi,

I have the latest mongoose 3.8.16 with mongodb 2.6.4

I am trying to do cursor operation on an aggregate pipeline.

My function looks like,

var where = {  "storeId": storeId };
MongoBasket.aggregate()
                            .match(where)
                            .group({
                                "basketProducts": {
                                    "$push": "$basketProduct"
                                },
                                "basketIds": {
                                    "$push": "$basketId"
                                },
                                "storeId": {
                                    "$addToSet": "$storeId"
                                },
                                "consumerIds": {
                                    "$push": "$consumerId"
                                },
                                "basketTransactionCardTotal": {
                                    "$push": "$basketTransactionCard"
                                },
                                "basketTransactionCashTotal": {
                                    "$push": "$basketTransactionCash"
                                },
                                "totalTip": {
                                    "$push": "$tip"
                                },
                                "_id": {
                                    "year": {
                                        "$year": "$completed"
                                    },
                                    "month": {
                                        "$month": "$completed"
                                    },
                                    "day": {
                                        "$dayOfMonth": "$completed"
                                    },
                                    "hour": {
                                        "$hour": "$completed"
                                    }
                                }
                            })
                            .sort({_id: 1})
                            .cursor({
                                batchSize: 200000
                            })
                            .exec(function(err, result) {
                                 console.log(err, result);
                            }, req.messageInstance);

I printed the raw mongodb query that is built by mongoose (using mongoose.set('debug', true)) which looks like

baskets.aggregate([
    {
        '$match': {
            storeId: 11
        }
    },
    {
        '$group': {
            _id: {
                hour: {
                    '$hour': '$completed'
                },
                day: {
                    '$dayOfMonth': '$completed'
                },
                month: {
                    '$month': '$completed'
                },
                year: {
                    '$year': '$completed'
                }
            },
            totalTip: {
                '$push': '$tip'
            },
            basketTransactionCashTotal: {
                '$push': '$basketTransactionCash'
            },
            basketTransactionCardTotal: {
                '$push': '$basketTransactionCard'
            },
            consumerIds: {
                '$push': '$consumerId'
            },
            storeId: {
                '$addToSet': '$storeId'
            },
            basketIds: {
                '$push': '$basketId'
            },
            basketProducts: {
                '$push': '$basketProduct'
            }
        }
    },
    {
        '$sort': {
            _id: 1
        }
    }
]){
    cursor: {
        batchSize: 200000
    }
}

Please note that cursor operator is outside the aggregate () enclosure

]){
    cursor: {
        batchSize: 200000
    }
}

Shouldn't it be like

],
{
    cursor: {
        batchSize: 200000
    }
})

My hand written raw mongodb query for mongo shell works really well and here is how it looks


db.baskets.aggregate([
    {
        "$match": {
            storeId: 11
        }

    },
    {
        "$group": {
            "_id": {
                "year": {
                    "$year": "$completed"
                },
                "month": {
                    "$month": "$completed"
                },
                "day": {
                    "$dayOfMonth": "$completed"
                },
                "hour": {
                    "$hour": "$completed"
                }
            },
            "totalTip": {
                "$push": "$tip"
            },
            "basketTransactionCashTotal": {
                "$push": "$basketTransactionCash"
            },
            "basketTransactionCardTotal": {
                "$push": "$basketTransactionCard"
            },
            "consumerIds": {
                "$push": "$consumerId"
            },
            "storeId": {
                "$addToSet": "$storeId"bas
            },
            "basketIds": {
                "$push": "$basketId"
            },
            "basketProducts": {
                "$push": "$basketProduct"
            }
        }
    },
    {
        "$sort": {
            _id: 1
        }
    }
],
{
    cursor: {
        batchSize: 2000000
    }
})

Is it a bug or am I missing something?

If someone could shred some light on it would be much appreciated.

Many thank,

Karthik

@webjay
Copy link

webjay commented Sep 19, 2014

I have the same problem with the same versions.

This works:

return Rx.Observable.fromPromise(Meeting.aggregate(pipeline).exec());

This doesn't work:

return Rx.Observable.fromPromise(Meeting.aggregate(pipeline).cursor({ batchSize: 1000 }).exec());

@vkarpov15 vkarpov15 added this to the 3.8.18 milestone Sep 19, 2014
@mithralaya
Copy link
Author

Thanks for adding it to your milestone.

Many thanks,
Karthik

@vkarpov15 vkarpov15 modified the milestones: 3.8.19, 3.8.18 Oct 22, 2014
@vkarpov15 vkarpov15 modified the milestones: 3.8.20, 3.8.19 Nov 7, 2014
@mattbryson
Copy link

Hi, Any progress on this?

@vkarpov15
Copy link
Collaborator

Some progress, but not much unfortunately. We've figured out what's wrong, just haven't had the time to fix it yet.

@chrisjhoughton
Copy link

+1. Any progress on this?

@vkarpov15
Copy link
Collaborator

So this issue is closed, what sort of problem are you having?

@chrisjhoughton
Copy link

This works:

Model
.aggregate(pipeline)
.exec(function () {
  console.log(arguments);
})

And this doesn't: (never calls back)

Model
.aggregate(pipeline)
.cursor({ batchSize: 1000 })
.exec(function () {
  console.log(arguments);
})

Also, the following doesn't return a promise:

Model
.aggregate(pipeline)
.cursor({ batchSize: 1000 })
.exec()

Am I missing something?

@vkarpov15
Copy link
Collaborator

Model
.aggregate(pipeline)
.cursor({ batchSize: 1000 })
.exec()

returns a cursor, as specified in 4.0 release notes. Admittedly this is a not-well-designed API, it's something that was thrown in at the last minute as a stopgap. The right way to do it would probably be something like this:

var stream = Model
.aggregate(pipeline)
.cursor({ batchSize: 1000 })
.exec().stream();

stream.on('data', function(doc) {
  // ...
});

See mongodb driver cursor docs

@chrisjhoughton
Copy link

Ok cool, thanks for that! For the callback approach, the docs currently say this:

screen shot 2015-05-03 at 08 46 58

This is incorrect, right?

@vkarpov15
Copy link
Collaborator

Yep those docs are incorrect, thanks for pointing that out

@timjnh
Copy link

timjnh commented Jul 23, 2015

Anyone looking at this may also be interested in #3160 which outlines another bug about getting an undefined response from exec when a cursor is used.

@radiumrasheed
Copy link

@vkarpov15 its almost 2018 and the docs are still misleading. someone help 🤔

@vkarpov15
Copy link
Collaborator

@Ra1da35ma well that's embarrassing, looks like we closed out #2955 by mistake. Thanks for pointing that out, re-opened and will be fixed 👍

@jaffarc
Copy link

jaffarc commented Mar 9, 2018

I returned to the version mongoose": "4.13.7 and everything is normal .. using mongo 3.6

@gucompi
Copy link

gucompi commented May 26, 2019

This works:

Model
.aggregate(pipeline)
.exec(function () {
  console.log(arguments);
})

And this doesn't: (never calls back)

Model
.aggregate(pipeline)
.cursor({ batchSize: 1000 })
.exec(function () {
  console.log(arguments);
})

Also, the following doesn't return a promise:

Model
.aggregate(pipeline)
.cursor({ batchSize: 1000 })
.exec()

Am I missing something?

This Answer + This One:

I returned to the version mongoose": "4.13.7 and everything is normal .. using mongo 3.6

Solved my problem. Thanks!

@Automattic Automattic locked as resolved and limited conversation to collaborators May 27, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants