I have a collection, which I would like to perform an aggregation on and put the result into a separate collection in the same database. While scrutinizing the docs, I stumbled upon $merge which works exactly the way I want. I came up with the following mongo shell pipeline, which works flawlessly.
db.getCollection('SOURCE_COLLECTION').aggregate([
{
"$match": {type: 'ABC'}
},
{
"$merge": {
"into": "OUTPUT_COLLECTION",
"whenMatched": "replace"
}
}
])
Now, I need the same effect in Spring boot, for which I have come up with the following, which theoretically should be no different.
final ArrayList<Document> pipeline = new ArrayList<>();
pipeline.add(Document.parse("{$match: {type: 'ABC'}}"));
pipeline.add(Document.parse("{$merge: {into: 'OUTPUT_COLLECTION', whenMatched: 'replace'}}"));
mongoTemplate.getDb()
.getCollection("SOURCE_COLLECTTION", Document.class)
.aggregate(pipeline);
Nonetheless, this ain't working. As it can bee seen, I am using MongoCollection<T>.aggregate() method, which takes a List<Document> as a pipeline. Each stage in the pipeline is generated by parsing a JSON string into a document.
Interestingly, when I replace merging with $out, it works without any issue.
final ArrayList<Document> pipeline = new ArrayList<>();
pipeline.add(Document.parse("{$match: {type: 'ABC'}}"));
pipeline.add(Document.parse("{$out: 'OUTPUT_COLLECTION'}"));
mongoTemplate.getDb()
.getCollection("SOURCE_COLLECTTION", Document.class)
.aggregate(pipeline);
But this is no good to me, as this aggregation will be executed multiple times (actually I am trying to populate a materialised view kind of a collection here). I'd need $merge to work, but it doesn't. What am I missing? Can someone see something that I haven't?