Search code examples
mongodbmongo-javamongo-java-drivermongo-scala-driver

How to create Decimal128 field with inc operator in java/scala


I have following document structure:

{
    "moneys": {
      "someKey": NumberDecimal(99)
      ...
      "someOtherRandomKey": NumberDecimal(99)
    }
{

What I want: When nonexistent field increments, create that field with NumberDecimal value.

I tried it with scala driver but cant do that:

//not compiles
collection.findOneAndUpdate(filters,Updates.inc("someOtherKey", new Decimal128(50)))

because Updates.inc(k,v) requires Number; Decimal128 is not Number

I think problem not in driver, but with my logic.

How can I implement my case with scala/java driver?


Solution

  • Problem solved by implementing codec for scala.math.BigDecimal:

    class BigDecimalScalaCodec extends Codec[scala.math.BigDecimal] {
    
      override def encode(writer: BsonWriter, value: scala.math.BigDecimal, encoderContext: EncoderContext): Unit = {
        writer.writeDecimal128(new Decimal128(value.bigDecimal))
      }
    
      override def getEncoderClass: Class[scala.math.BigDecimal] = classOf[scala.math.BigDecimal]
    
      override def decode(reader: BsonReader, decoderContext: DecoderContext): scala.math.BigDecimal = {
        reader.readDecimal128().bigDecimalValue()
      }
    }
    

    Register in mongo:

     val codecRegistry = fromRegistries(fromCodecs(new BigDecimalScalaCodec()), DEFAULT_CODEC_REGISTRY)
    
     val database: MongoDatabase = mongoClient.getDatabase("dbName")
        .withCodecRegistry(codecRegistry)
    

    And now we can use scala.math.BigDecimal:

    collection.findOneAndUpdate(filters,Updates.inc("someOtherKey", BigDecimal(99))