Java Mongo DB update Query using aggregation pipeline using $subtract on DateTime field, $match, $project not working

80 Views Asked by At

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

0

There are 0 best solutions below