octomix / josson

A query language for JSON and a template engine to generate text output.
Apache License 2.0
31 stars 8 forks source link

The min() function return value in scientific format #13

Closed albinth12 closed 2 weeks ago

albinth12 commented 11 months ago

For the model [ { "request_amount": 1000, "request_currency": "INR", "value_date": "2023-09-04" }, { "request_amount": 1001, "request_currency": "INR", "value_date": "2023-09-04" } ]

when finding max(),min() and sum() for request_amount field the min() function return minimum value in scientific format.The max() and sum() returning in the correct format.

output log

total amount calculated 2001.0 maximum amount 1001 minimum amount 1E+3

code new BigDecimal(josson.getNode("request_amount.sum()").asText()); log.debug("maximum amount {}", josson.getString("request_amount.max()")); log.debug("minimum amount {}", josson.getString("request_amount.min()"));

octomix commented 11 months ago

it is strange that my testing output is 1000 instead of 1E+3. I've tested with different version of JDK, all output 1000.

How about function getInteger()?

josson.getInteger("request_amount.min()")
albinth12 commented 11 months ago

I am using jdk17 .The getIntger() will not helpfull because it's an amount field which can hold a large amount value.

And noted one thing for the value 1000 only its formating to scientific form.If I have provided greater than ot less than 1000 getting proper format value.And the issue is when creating a josson objects from pojo objects the value is coming in scientific format.Below provided the josson object

{ "root" : [ { "request_amount" : 1E+3, "request_currency" : "INR", "value_date" : "2023-09-05", "bank_entityid" : "INDIA", "country" : "IN", "entity_id" : "55456001-5713-504a-9396-9d7f10f9ac22" }, { "request_amount" : 1001, "request_currency" : "INR", "value_date" : "2023-09-05", "bank_entityid" : "INDIA", "country" : "IN", "entity_id" : "55456001-5713-504a-9396-9d7f10f9ac22" } ], "node" : [ { "request_amount" : 1E+3, "request_currency" : "INR", "value_date" : "2023-09-05", "bank_entityid" : "INDIA", "country" : "IN", "entity_id" : "55456001-5713-504a-9396-9d7f10f9ac22" }, { "request_amount" : 1001, "request_currency" : "INR", "value_date" : "2023-09-05", "bank_entityid" : "INDIA", "country" : "IN", "entity_id" : "55456001-5713-504a-9396-9d7f10f9ac22" } ], "rootAsObject" : null, "rootAsArray" : [ { "request_amount" : 1E+3, "request_currency" : "INR", "value_date" : "2023-09-05", "bank_entityid" : "INDIA", "country" : "IN", "entity_id" : "55456001-5713-504a-9396-9d7f10f9ac22" }, { "request_amount" : 1001, "request_currency" : "INR", "value_date" : "2023-09-05", "bank_entityid" : "INDIA", "country" : "IN", "entity_id" : "55456001-5713-504a-9396-9d7f10f9ac22" } ] }

complete function code

public void setFinancialFieldsForFLA(final BatchModel batchModel, final List models) throws CBXException { log.debug("IN -> getRequestAmountForFLAConfiguration"); Josson josson = Josson.from(models); log.debug("josson {}",Josson.toJsonPretty(josson)); final BigDecimal result = new BigDecimal(josson.getString("request_amount.sum()")); log.debug("total amount calculated {}", result); batchModel.setTotal_amount(result); batchModel.setMax_amount(new BigDecimal(josson.getRequiredString("request_amount.max()"))); batchModel.setMin_amount(new BigDecimal(josson.getRequiredString("request_amount.min()"))); log.debug("min and max amount {} {}", batchModel.getMin_amount(), batchModel.getMax_amount()); batchModel.setTransaction_date(josson.getNode("distinct(value_date)").get(0).asText()); batchModel.setCurrency(josson.getNode("distinct(request_currency)").get(0).asText()); }

octomix commented 11 months ago

It may be Jackson ObjectMapper issue. Please try this statement to setup first:

Mapper.mapper()
        .enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
        .enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);

BTW, it is bad idea to convert number to String and then back to BigDecimal. Maybe you can use:

BigDecimal result = BigDecimal.valueOf(josson.getDouble("request_amount.sum()"));
BigDecimal max = BigDecimal.valueOf(josson.getDouble("request_amount.max()"));
BigDecimal min = BigDecimal.valueOf(josson.getDouble("request_amount.min()"));

In addition, I think function distinct() is not necessary before you get the first array element. i.e.:

String date = josson.getString("[0].value_date");
String currency = josson.getString("[0].request_currency");