I am using below mongo aggregation pipeline in spring boot java to update document in mongodb. Below is the raw mongo query that works fine when executed directly on mongodb
db.lock.aggregate([
{
"$project": {
"_id": 1,
"ownerId": 1,
"releaseTs": 1,
"auditCreateTs": 1,
"auditUpdateTs": 1,
"difference": {
"$divide": [
{
"$subtract": [
new Date(),
"$releaseTs"
]
},
1000
]
}
}
},
{
"$match": {
"$and": [
{
"_id": "magpie"
},
{
"$or": [
{
"ownerId": "reena"
},
{
"difference": {
"$gt": 10
}
}
]
}
]
}
},
{
"$set": {
"ownerId": "Jivii"
}
},
{
"$merge": {
into: "lock",
on: [
"_id"
],
// Optional
whenMatched: "replace",
// Optional
whenNotMatched: "discard"// Optional
}
}
])
I have tried to convert above query in java, but facing below issues with java code:
- Match criteria is not working (involves use of $or and $and operator), so the actual documents are not updated in mongodb collection.
- Is there any way to get the count of documents updated when this aggregate function is executed?
I am writing match criteria condition here in simple language, so someone can help to point what's wrong in below aggregation query.
Update the document where _id is "x101" AND (OwnerId = "testUser1" OR Difference between current_timestamp ,releaseTs is greater than certain value)
//Get the time difference in seconds
String jsonExpression = "{\"$divide\": [{\"$subtract\":[new ISODate(),\"$releaseTs\"]},1000]}";
AggregationOperation project = Aggregation.project().andInclude("_id","ownerId", "releaseTs", "auditCreateTs","auditUpdateTs").and(context -> context.getMappedObject(Document.parse(jsonExpression))).as("difference");
Criteria firstCond = Criteria.where("_id").is("x101");
Criteria secondOrCond = new Criteria().orOperator(
Criteria.where("ownerId").is("testUser1").and("difference").gt(lockTimeoutInSecs));
AggregationOperation match = Aggregation.match(new Criteria().andOperator(firstCond,secondOrCond));
AddFieldsOperation update = Aggregation.addFields().addFieldWithValue("ownerId", ownerId).addFieldWithValue("releaseTs", now.plusSeconds(lockTimeoutInSecs))
.addFieldWithValue("auditUpdateTs", now).build();
MergeOperation merge = Aggregation.merge().id(UniqueMergeId.id()).intoCollection("lock").build();
List<AggregationOperation> aggOps = new ArrayList<>();
aggOps.add(project);
aggOps.add(match);
aggOps.add(update);
aggOps.add(merge);
Aggregation aggregation = Aggregation.newAggregation(aggOps);
int count = mongoTemplate.aggregate(aggregation, Lock.class, Lock.class).getMappedResults().size();
Mongodb version is 5.0.2, driver version is 4.2
springsyntax