I am trying to implement this solution in rails, using the collection aggregate method
, to clone an entire collection within the same database.
In mongo shell, this works perfectly, and a cloned collection is created successfully:
db.source_collection.aggregate([ { $match: {} }, { $out: "target_collection" } ])
The rails
-mongoid
alternate, according to my research, should be this, which runs without errors:
SourceCollection.collection.aggregate({"$match" => {}, "$out" => "target_collection"})
#<Mongo::Collection::View::Aggregation:0x000000055bced0 @view=#<Mongo::Collection::View:0x44951600 namespace='DB_dev.source_collection' @filter={} @options={}>, @pipeline={"$match"=>{}, "$out"=>"target_collection"}, @options={}>
I also tried with an array
SourceCollection.collection.aggregate([{"$match" => {}}, {"$out" => "target_collection"}])
#<Mongo::Collection::View::Aggregation:0x000000054936d0 @view=#<Mongo::Collection::View:0x44342320 namespace='DB_dev.source_collection' @filter={} @options={}>, @pipeline=[{"$match"=>{}}, {"$out"=>"target_collection"}], @options={}>
UPDATE
This simplest syntax also works in Mongo console:
db.source_collection.aggregate( { $out: "target_collection" } )
But the respective syntax does not seem to work in Ruby:
SourceCollection.collection.aggregate({"$out" => "target_collection"})
Unfortunately, although there are no errors, the collection is not created.
Any clues as to the way I can make this happen? Mongo gem version 2.5.3
Update2
Apparently $out is not considered in the pipeline, thus rendering the aggregation invalid.
This can be fixed with code... I am looking for a module/class/method override, as contacting mongodb issue tracking system for a change request might not be as quick..
UPDATE - FINAL
This issue has been solved, by help of Thomas R. Koll (thank you).
I add an update to post the response I got from the ticketing service of MongoDB, which pretty much describes Thomas's solution.
The reason you're not seeing the results without
count
is that theaggregate
method returns a lazy cursor; that is, the query does not execute until the return value ofaggregate
is iterated over. Callingcount
is one way to do this. This is the same behavior you'll see if you callfind
or if you callaggregate
without specifying$out
; the difference is that$out
has an side-effect beyond just returning the results, so it's more obvious when exactly it occurs.