Hi how can check what index use , and number of scanned objects in aggregate query , something similar to
db.collection.find().explain() ?
Right now, there is no explain functionality for aggregate() yet. However, in general indexes are only used for certain operators if they are the first element in the aggregation operator pipeline. For example, $match and $geoNear.
So in order to figure out which index is being used, simply run the explain() on a find() where the query matches your first $match options.
explain() functionality for aggregate() is an issue in JIRA: https://jira.mongodb.org/browse/SERVER-4504 — I would suggest you vote for the issue on JIRA as well.
Related
Are there any elements within the output of MongoDB's explain("executionStats") that gives an idea or a hint about - whether the query is using a given index for filtering or sorting or for both?
I read the following URLs
Mongodb compound indexes for filtering and sorting on BIG collection [points to below URL and has brief discussion]
https://emptysqua.re/blog/optimizing-mongodb-compound-indexes/ [ this one gives general idea, but the explain output uses older format/elements that don't exist in Mongodb 4.0 that I am using ]
https://docs.mongodb.com/manual/tutorial/sort-results-with-indexes/ [documents how to determine the index and leverage index prefixes, but does show explain output confirming the usage]
From MongoDB Docs:
If MongoDB can use an index scan to obtain the requested sort order,
the result will not include a SORT stage. Otherwise, if MongoDB cannot
use the index to sort, the explain result will include a SORT stage.
Example:
Look at the sample data from sortop collection.
Explain plan for a query without index:
Create Index on the collection:
Run the same query and check SORT stage in explain plan:
Is there any way to force a find() or aggregate() query to refer/see a particular existing index in MongoDB. I am asking about the the scenario when a collection has more than one compound indexes.
Yes, $hint is there for that. As mentioned in the documentation, you can use it like that:
db.users.find().hint( { age: 1 } )
What you put in argument is the definition of the index, and not its name. This query would force the use of the index on the age field. I'm not sure though whether it works for aggreate() call as well or not.
Aggregation does not support $hint. There is a open item in MongoDB
https://jira.mongodb.org/browse/SERVER-7944
I need to query documents with mongoDb that contain nested arrays. I see a lot of examples using the simple $in operator. The only problem is that I strictly need to check for proper subsets.
Consider the following document.
{data: [[1,2,3], [4,5,6]]}
The query needs to be able to get documents with all of [1,2,3] where 1,2,3 can be in any order, which rules out the following query, because it will only match in the correct order.
{data:{$elemMatch:{$all:[[1,2,3]]}}}
I've also tried nested $elemMatch operators with no success, because the $in operator will return the document even if only one element matches such as the following.
{data:{$elemMatch:{$elemMatch:{$in:[1,4]}}}}
Not sure what your actual query looks like, but this should do what you need:
db.documentDto.find({"some_field":{"$elemMatch":{"$in":[1,2,3]}} })
I haven't got a complete answer (and not much time as its late here) but I would consider
Using aggregation pipeline instead of a query if your not already
Use $unwind operator to deconstruct your nested arrays
Use $sort to sort the contents of the arrays - so you can now compare
Use $match to filter out the arrays which don't fit the array subset values as you can now check based on order.
Use $group to group the result back together based on the _id value
Ref:
http://docs.mongodb.org/manual/reference/operator/aggregation-pipeline/ will give you info on each of the above.
From a quick search I came up with a similar question/example that might be helpful: Mongodb sort inner array
I am still a bit humble with mongo queries, is it possible, or - regarding performance - necessary, to put the following MongoDB query into a smarter form? Does the double use of $elemMatch affect performance?
Example for a db full of chicken-coops:
{chickens: {$elemMatch: {recentlyDroppedEggs: {$elemMatch:{appearance:"red-blue-striped"}}}}}
for finding all chicken coops that have a chicken (in its chickens-array) which recently dropped a red-blue-striped egg (into its recentlyDroppedEggs-array).
Thanks for any hints!
No, you don't need $elemMatch for that. You could just use:
{'chickens.recentlyDroppedEggs.appearance': 'red-blue-striped'}}}}
$elemMatch is typically only needed when you want to match multiple fields in an array element or apply multiple operators to a single field (e.g. $lt and $gt).
What is the difference between the $match operator used inside the aggregate function and the regular find in Mongodb?
Why doesn't the find function allow renaming the field names like the aggregate function?
e.g. In aggregate we can pass the following string:
{ "$project" : { "OrderNumber" : "$PurchaseOrder.OrderNumber" , "ShipDate" : "$PurchaseOrder.ShipDate"}}
Whereas, find does not allow this.
Why does not the aggregate output return as a DBCursor or a List? and also why can't we get a count of the documents that are returned?
Thank you.
Why does not the aggregate output return as a DBCursor or a List?
The aggregation framework was created to solve easy problems that otherwise would require map-reduce.
This framework is commonly used to compute data that requires the full db as input and few document as output.
What is the difference between the $match operator used inside the aggregate function and the regular find in Mongodb?
One of differences, like you stated, is the return type. Find operations output return as a DBCursor.
Other differences:
Aggregation result must be under 16MB. If you are using shards, the full data must be collected in a single point after the first $group or $sort.
$match only purpose is to improve aggregation's power, but it has some other uses, like improve the aggregation performance.
and also why can't we get a count of the documents that are returned?
You can. Just count the number of elements in the resulting array or add the following command to the end of the pipe:
{$group: {_id: null, count: {$sum: 1}}}
Why doesn't the find function allow renaming the field names like the aggregate function?
MongoDB is young and features are still coming. Maybe in a future version we'll be able to do that. Renaming fields is more critical in aggregation than in find.
EDIT (2014/02/26):
MongoDB 2.6 aggregation operations will return a cursor.
EDIT (2014/04/09):
MongoDB 2.6 was released with the predicted aggregation changes.
I investigated a few things about the aggregation and find call:
I did this with a descending sort in a table of 160k documents and limited my output to a few documents.
The Aggregation command is slower than the find command.
If you access to the data like ToList() the aggregation command is faster than the find.
if you watch at the total times (point 1 + 2) the commands seem to be equal
Maybe the aggregation automatically calls the ToList() and does not have to call it again. If you dont call ToList() afterwards the find() call will be much faster.
7 [ms] vs 50 [ms] (5 documents)