I am trying to perform an update on a document in a Mongo collection. The query used to find and update a record is as below and works fine.
StringBuilder queryBuilder = new StringBuilder()
.append("{"date": ")
.append(startOfDayEpoch)
.append(", "key": "")
.append(key)
.append("", "appId": "")
.append(appId)
.append("", "assetId": "")
.append(assetId)
.append(""")
.append("}");
Update increment = processRequestCount ? Update.fromDocument(Document.parse("{"$inc": {"usedHits": "
+ withCalculatedHits + ", "requestCount": 1}}")) :
Update.fromDocument(Document.parse("{"$inc": {"usedHits": " + withCalculatedHits + "}}"));
UpdateResult result = mongoTemplate.updateFirst(matchClause, increment, proxyCollection);
if (result.getMatchedCount() > 0)
return true;
Problem :
I now tried to update two more fields witht the above clause as per below
-
First is to add a condition clause in the above for a scenario like
if usedHits > freeHits => update -> costCalculated = (freeHits-usedHits) * multiplier
-
maintain a statusCode object which increments with every request with a specific status code. For eg
statusCode : 200=10, 400=3, 503=1
When a request comes and is responded with a status code lets say 400, it should update the statusCode.400 value by 1
I tired modifying the increment Update clause using online references as below when adding the condition clause but it didn’t work with the below error
Document documentToUpdate = new Document("$set", new Document("costCalculated", new Document("$cond",
Arrays.asList(new Document("$gte", Arrays.asList("$usedHits", freeHits)),
new Document("$mul", Arrays.asList(new Document("$subtract", Arrays.asList("$usedHits", freeHits)), multiplier)),
0))));
documentToUpdate.append("$inc", new Document("statusCodes."+statusCode, 1));
Update increment = Update.fromDocument(documentToUpdate);
Error : org.springframework.dao.DataIntegrityViolationException: The dollar ($) prefixed field '$cond' in 'costCalculated.$cond' is not valid for storage.; nested exception is com.mongodb.MongoWriteException: The dollar ($) prefixed field '$cond' in 'costCalculated.$cond' is not valid for storage.;
Note: I am trying to avoid pulling object first and perform the changes and write back to db but just issue an update
Also, the final document would look like
{
"date": 1712341800,
"expiresAfter": 1714413600,
"key": "my_dev_key",
"appId": "my_app_id",
"assetName": "Sample API",
"assetId": "asset_id",
"usedHits": 11,
"statusCodes": {
"404": 1,
"200": 11
},
"costCalculated": 2.2,
"requestCount": 12
}
Could anyone please guide and point what is wrong or suggest an approach for this?