How to update many records with `dateAdd` in Java

With a collection of

[
  {
    "user": "abc",
    "seconds": 1111,
    "time": ISODate("2020-05-05T00:00:00Z")
  },
  {
    "user": "abc",
    "seconds": 2222,
    "time": ISODate("2020-05-05T00:00:00Z")
  }
]

I need to add another field, which adds the seconds to the time of individual records.

This seems to be possible with dateAdd which is added in version 5 (the database is version 5).

However, I am not able to achieve that with MongoDB Java driver 4.6.0 .

I have tried:

var alerts = db.getCollection("alerts");

alerts.updateMany(eq("user", user),
        set(new Field<>("time2",
                new Document("$dateAdd",
                        new Document("startDate", "$time")
                                .append("unit", "second")
                                .append("amount", "$seconds"))
        )));

Thanks a lot.

There is nothing specific to the driver version for this.

But without more information, log, trace or data after update, about what is happening, error, wrong result, warning, we cannot really help.

The only thing I can think is that since auto reference fields from the existing documents you might need to use the syntax

Sorry for not being clear.

Let’s say we have:

db.alerts.insertMany( [
   { _id: 1, seconds: 86400 },
   { _id: 2, seconds: 172800 }
] )

the following works fine on the shell, which sets field time to be now plus the seconds fields.

db.alerts.updateMany({}, [
    {
        $set: { time: {
                $dateAdd: {
                    startDate: "$$NOW",
                    unit: "second",
                    amount: "$seconds"
                }
        } }
    }
])

The issue is that I don’t know how to transfer this to Java, for example:

var alerts = db.getCollection("alerts");

alerts.updateMany(new Document(),
    set(new Field<>("time",
        eq("$dateAdd",
            new Document("startDate", "$$NOW")
                .append("unit", "second")
                .append("amount", "$seconds")))));

produces an object with

  "time": {
    "$dateAdd": {
      "startDate": "$$NOW",
      "unit": "second",
      "amount": "$seconds"
    }
  }

I am under the impression that dateAdd should be added to the Java driver (in Aggregate class).

The culprit must be the eq() builder. I don’t think it can be used in this context. The $dateAdd is implemented in the server, so it should work.

Try to simply replace eq with new Document.

Thanks, eq is behaving as new Document.

After enabling profiling and checking the different, the reason is:

alerts.updateMany(doc, eq(...)) doesn’t work

but

alerts.updateMany(doc, List.of(eq(...))) works.

In other words:

updateMany(Bson filter, Bson update) doesn’t work

but

updateMany(Bson filter, List<? extends Bson> update) does.

I would consider this a bug, but I guess the team would be better be able to evaluate it.

1 Like