Reputation: 2405
I'm running the following aggregation query on a test database
db.restaurants.explain().aggregate([
{$match: {"address.zipcode": {$in: ["10314", "11208", "11219"]}}},
{$match: {"grades": {$elemMatch: {score: {$gte: 1}}}}},
{$group: {_id: "$borough", count: {$sum: 1} }},
{$sort: {count: -1} }
]);
And as per MongoDB documentation it should return cursor that I can iterate and see data about all pipeline stages:
The operation returns a cursor with the document that contains detailed information regarding the processing of the aggregation pipeline.
However the aggregation command returns explain info only about first two match stages:
{
"stages" : [
{
"$cursor" : {
"query" : {
"$and" : [
{
"address.zipcode" : {
"$in" : [
"10314",
"11208",
"11219"
]
}
},
{
"grades" : {
"$elemMatch" : {
"score" : {
"$gte" : 1.0
}
}
}
}
]
},
"fields" : {
"borough" : 1,
"_id" : 0
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.restaurants",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"grades" : {
"$elemMatch" : {
"score" : {
"$gte" : 1.0
}
}
}
},
{
"address.zipcode" : {
"$in" : [
"10314",
"11208",
"11219"
]
}
}
]
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [
{
"grades" : {
"$elemMatch" : {
"score" : {
"$gte" : 1.0
}
}
}
},
{
"address.zipcode" : {
"$in" : [
"10314",
"11208",
"11219"
]
}
}
]
},
"direction" : "forward"
},
"rejectedPlans" : []
}
}
},
{
"$group" : {
"_id" : "$borough",
"count" : {
"$sum" : {
"$const" : 1.0
}
}
}
},
{
"$sort" : {
"sortKey" : {
"count" : -1
}
}
}
],
"ok" : 1.0
}
And the object returned does not seem like cursor at all.
If I save the aggregation result to a variable and then try to iterate through it using cursor methods (hasNext(), next()
, etc) I get the following:
TypeError: result.next is not a function : @(shell):1:1
How can I see info on all pipeline steps?
Thanks
Upvotes: 2
Views: 3409
Reputation: 9285
1. Explain info
Explain() returns the winning plan of a query, ie how the database fetch the document before processing them in the pipeline.
Here, because adress.zipcode
and grades
aren't indexed, the db performs a COLLSCAN
, ie iterate over all documents in db and see if they match
After that, you group the document and sort the results. Thoses operations are done "in memory", on the previously fetched documents. The fields aren't indexed, so no special plan can be used here
more info here : explain results
2. Explain() on aggregation query does not return a cursor
For some reason, explain()
on aggregation query does not return a cursor, but a BSON object directly (unlike explain()
on find()
query )
It might be a bug, but there's nothing about this in the doc.
Anyway, you can do :
var explain = db.restaurants.explain().aggregate([
{$match: {"address.zipcode": {$in: ["10314", "11208", "11219"]}}},
{$match: {"grades": {$elemMatch: {score: {$gte: 1}}}}},
{$group: {_id: "$borough", count: {$sum: 1} }},
{$sort: {count: -1} }
]);
printjson(explain)
Upvotes: 4