-
Type: Bug
-
Resolution: Fixed
-
Priority: Minor - P4
-
Affects Version/s: None
-
Component/s: None
-
None
-
Fully Compatible
When aggregate method is called on a view, i.e.
collection.find({}).aggregate
... if any conditions are passed to find, these conditions will not be utilized by the aggregate method.
This behavior can be surprising to users and should be documented.
We could potentially pass the conditions by wrapping them into a $match stage, however this likely would violate the "no helpers" driver mantra.
Currently the reference documentation only describes Collection#aggregate method and does not document View#aggregate at all, thus there is no existing place in our reference documentation to add this caveat to. This ticket is to document this situation; if any behavior changes are made, likely they should be done as part of https://jira.mongodb.org/browse/RUBY-2706.
Original report:
The current implementation of mongo v1.15 :find public_methods shows that :aggregate can be run, implying that an aggregate() ran on a preceding find() would be bound by the find()'s search parameters.
client = Mongo::Client.new col = 'test' client[col].find.methods.grep(/aggregate/) => [:aggregate]
For example, assuming a collection of 50 records, half of which have a boolean value of { find_me: true }.
irb(main):> (1..25).each { |i| client[col].insert_one({}) } => 1..25 irb(main):> (1..25).each { |i| client[col].insert_one({ find_me: true }) } => 1..25 irb(main):> client[col].count => 50 irb(main):> client[col].find({ find_me: true }).count => 25
Since we can run an aggregate() on the above find() cursor, I assumed that that aggregate pipeline would be bound by the above search of { find_me: true } with 25 documents and therefor not require a { $match } stage. But that does not appear to be the case:
irb(main):> client[col].find({ find_me: true }).aggregate([]).count
=> 50
This shows the find() should just be excluded as it is completely ignored by the follow-up aggregate().
Since this issue was found in only one place of my code where I patched an existing find() with a follow-up aggregate(), assuming the aggregate() would only apply to the find()'s returned documents, I will resolve my own code's bug by removing the find() and just running an aggregate() with the needed { $match } stage.
My point in opening this bug is that since an aggregate() can be ran on a find(), it can give the false assumption that the aggregate() assumes the preceding find()'s returned documents (25). But instead, it entirely ignores the preceding find()'s returned docs and runs on the full collection's documents (50).
Perhaps :aggregate should not be an available method of :find within the Ruby Mongo driver.
- is related to
-
MONGOID-5270 Implement .tally method for Mongoid#Criteria
- Closed
-
MONGOID-5395 Call aggregate directly on collection instead of on find view
- Closed
- related to
-
RUBY-2706 Find options are not correctly propagated in a number of cases
- Closed