XContentBuilder.field() method doesn't provide overload for BigDecimal


(Jondow) #1

I'm working on a Grails project that uses the ElasticSearch plugin for
Grails. The author of the plugin has done a great job, but I've encountered
an issue that I believe is rooted in the XContentBuilder class used to
build the JSON to index my domain class.

In the plugin, the code determines a suitable marshaller for an object
based on its class. It would appear that for most of the standard classes,
this equates to using the plugins DefaultMarshaller, which effectively
calls XContentBuilder.field(String name, >Class of object< object).

Unfortunately looking at the ES source, there is no field(String,
BigDecimal) so it seems the default is called - field(String, Object),
which simply calls toString() on the class and as a result my JSON renders
a String instead of a numeric value for the BigDecimal, which is for a
price field in my domain class. This causes the indexing to fail for some
reason (which I haven't quite figured out what yet).

Is there a reason BigDecimal isn't overloaded? What approach should I use -
I've forked the ES Grails plugin code and am happy to make whatever changes
might be needed there and do a push request to the author.

Regards,
Darryl Pentz

--


(Jörg Prante) #2

Yes, it seems the XContentBuilder needs some love. BigDecimal is not
straightforward to output as it may produce a double or a string, whatever
the user prefers. By default it should map to a double, to allow numeric
range queries, and rounding should be like taught in school. For finer
control, BigDecimal fields output should be parametrized by a scale and a
rounding method (and a flag indicating what JSON field type is intended).

I opened a pull request:

Best regards,

Jörg

On Sunday, August 19, 2012 4:40:49 PM UTC+2, Jondow wrote:

I'm working on a Grails project that uses the ElasticSearch plugin for
Grails. The author of the plugin has done a great job, but I've encountered
an issue that I believe is rooted in the XContentBuilder class used to
build the JSON to index my domain class.

In the plugin, the code determines a suitable marshaller for an object
based on its class. It would appear that for most of the standard classes,
this equates to using the plugins DefaultMarshaller, which effectively
calls XContentBuilder.field(String name, >Class of object< object).

Unfortunately looking at the ES source, there is no field(String,
BigDecimal) so it seems the default is called - field(String, Object),
which simply calls toString() on the class and as a result my JSON renders
a String instead of a numeric value for the BigDecimal, which is for a
price field in my domain class. This causes the indexing to fail for some
reason (which I haven't quite figured out what yet).

Is there a reason BigDecimal isn't overloaded? What approach should I use

  • I've forked the ES Grails plugin code and am happy to make whatever
    changes might be needed there and do a push request to the author.

Regards,
Darryl Pentz

--


(Jondow) #3

Wow that looks great Jörg! Looks like that'll do the job perfectly. Look
forward to the updated ES lib.

Warm Regards,
Darryl

On Monday, 20 August 2012 14:55:35 UTC+2, Jörg Prante wrote:

Yes, it seems the XContentBuilder needs some love. BigDecimal is not
straightforward to output as it may produce a double or a string, whatever
the user prefers. By default it should map to a double, to allow numeric
range queries, and rounding should be like taught in school. For finer
control, BigDecimal fields output should be parametrized by a scale and a
rounding method (and a flag indicating what JSON field type is intended).

I opened a pull request:
https://github.com/elasticsearch/elasticsearch/pull/2188

Best regards,

Jörg

On Sunday, August 19, 2012 4:40:49 PM UTC+2, Jondow wrote:

I'm working on a Grails project that uses the ElasticSearch plugin for
Grails. The author of the plugin has done a great job, but I've encountered
an issue that I believe is rooted in the XContentBuilder class used to
build the JSON to index my domain class.

In the plugin, the code determines a suitable marshaller for an object
based on its class. It would appear that for most of the standard classes,
this equates to using the plugins DefaultMarshaller, which effectively
calls XContentBuilder.field(String name, >Class of object< object).

Unfortunately looking at the ES source, there is no field(String,
BigDecimal) so it seems the default is called - field(String, Object),
which simply calls toString() on the class and as a result my JSON renders
a String instead of a numeric value for the BigDecimal, which is for a
price field in my domain class. This causes the indexing to fail for some
reason (which I haven't quite figured out what yet).

Is there a reason BigDecimal isn't overloaded? What approach should I use

  • I've forked the ES Grails plugin code and am happy to make whatever
    changes might be needed there and do a push request to the author.

Regards,
Darryl Pentz

--


(system) #4