[Java driver] Change data type for a field in a collection

Hi!
Using the Mongo Sync Driver for Java, I am trying to change the data type in a field (from integer to decimal:

this.productCollection.updateMany(Filters.empty(),
                combine(Updates.set("custom-attributes.custom-attribute-integer", new BsonDocument("$toDecimal", "$custom-attributes.custom-attribute-integer")),
                        currentTimestamp("timestamp")));

But this syntax is not accepted. I have also tried by using an aggregation pipeline, with no result.
By using C# driver, this operation is more straightforward.

How can I implement this operation by using the Java drivers?

Hi @catalin and welcome in the MongoDB Community :muscle: !

Here you go:

    private static void transformingIntegersIntoDecimal128(MongoCollection<Document> coll) {
        Bson setDecimal128 = set("number", new Document("$toDecimal", "$number"));
        Bson setCurrentDate = set("currentDate", new Date());
        UpdateResult updateResult = coll.updateMany(empty(), asList(combine(setDecimal128, setCurrentDate)));
        System.out.println(updateResult);
    }

I think you are just missing the asList that’s changing the behaviour of the update from a “normal” update operation to an update that is using the aggregation pipeline which kinda changes everything here.

Here is the operation with all its context in a simple proof of concept / example:

package com.mongodb.quickstart;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.result.UpdateResult;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.json.JsonWriterSettings;

import java.util.Date;
import java.util.function.Consumer;

import static com.mongodb.client.model.Filters.empty;
import static com.mongodb.client.model.Updates.combine;
import static com.mongodb.client.model.Updates.set;
import static java.util.Arrays.asList;

public class Community {

    public static void main(String[] args) {
        String connectionString = System.getProperty("mongodb.uri");
        try (MongoClient mongoClient = MongoClients.create(connectionString)) {
            MongoCollection<Document> coll = mongoClient.getDatabase("test").getCollection("coll");
            System.out.println("Dropping collection 'test.coll'");
            coll.drop();
            System.out.println("Insert 2 sample docs...");
            insertSampleDocs(coll);
            printDocs(coll);
            System.out.println("Transform integers into Decimal128...");
            transformingIntegersIntoDecimal128(coll);
            printDocs(coll);
        }
    }

    private static void insertSampleDocs(MongoCollection<Document> coll) {
        coll.insertMany(asList(new Document("number", 42), new Document("number", 69)));
    }

    private static void transformingIntegersIntoDecimal128(MongoCollection<Document> coll) {
        Bson setDecimal128 = set("number", new Document("$toDecimal", "$number"));
        Bson setCurrentDate = set("currentDate", new Date());
        UpdateResult updateResult = coll.updateMany(empty(), asList(combine(setDecimal128, setCurrentDate)));
        System.out.println(updateResult);
    }

    private static void printDocs(MongoCollection<Document> coll) {
        coll.find(empty()).forEach(printDocuments());
    }

    private static Consumer<Document> printDocuments() {
        return doc -> System.out.println(doc.toJson(JsonWriterSettings.builder().indent(true).build()));
    }
}

Result in the console:

Dropping collection 'test.coll'
Insert 2 sample docs...
{
  "_id": {
    "$oid": "62a8ec50afc5b13f7c0ec2fe"
  },
  "number": 42
}
{
  "_id": {
    "$oid": "62a8ec50afc5b13f7c0ec2ff"
  },
  "number": 69
}
Transform integers into Decimal128...
AcknowledgedUpdateResult{matchedCount=2, modifiedCount=2, upsertedId=null}
{
  "_id": {
    "$oid": "62a8ec50afc5b13f7c0ec2fe"
  },
  "number": {
    "$numberDecimal": "42"
  },
  "currentDate": {
    "$date": "2022-06-14T20:15:12.644Z"
  }
}
{
  "_id": {
    "$oid": "62a8ec50afc5b13f7c0ec2ff"
  },
  "number": {
    "$numberDecimal": "69"
  },
  "currentDate": {
    "$date": "2022-06-14T20:15:12.644Z"
  }
}

Result in Mongosh:

> db.coll.find()
[
  {
    _id: ObjectId("62a8ec50afc5b13f7c0ec2fe"),
    number: Decimal128("42"),
    currentDate: ISODate("2022-06-14T20:15:12.644Z")
  },
  {
    _id: ObjectId("62a8ec50afc5b13f7c0ec2ff"),
    number: Decimal128("69"),
    currentDate: ISODate("2022-06-14T20:15:12.644Z")
  }
]

For this I’m using these version in Maven:

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven-compiler-plugin.source>8</maven-compiler-plugin.source>
<maven-compiler-plugin.target>8</maven-compiler-plugin.target>
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
<mongodb-driver-sync.version>4.6.0</mongodb-driver-sync.version>
<mongodb-crypt.version>1.4.0</mongodb-crypt.version>
<logback-classic.version>1.2.11</logback-classic.version>

See this pom.xml if you need.

Cheers,
Maxime.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.