Mapping for Different Type of Properties


(Spaeth) #1

In my application I have a class which is extended by two other classes. Those two other classes are serialized in json and indexed on elasticsearch.

The problem I'm facing is that those two classes extending the first one present a property with same name but different types (one string and the other one object) as follows:

>     {
>        "property1" : "a string",
>        "property2" : "another string"
>     }

>     {
>        "property1" : "this is ok as the first one is string too",
>        "property2" : {
>           "propertyFromProperty2" : "this is not ok"
>        }
>     }

When indexing I receive following exception:

>     org.elasticsearch.index.mapper.MapperParsingException: failed to parse [property2]
>         at org.elasticsearch.index.mapper.core.AbstractFieldMapper.parse(AbstractFieldMapper.java:418)
>         at org.elasticsearch.index.mapper.object.ObjectMapper.serializeObject(ObjectMapper.java:517)
>         at org.elasticsearch.index.mapper.object.ObjectMapper.parse(ObjectMapper.java:459)
>         at org.elasticsearch.index.mapper.object.ObjectMapper.serializeObject(ObjectMapper.java:517)
>         at org.elasticsearch.index.mapper.object.ObjectMapper.parse(ObjectMapper.java:459)
>         at org.elasticsearch.index.mapper.object.ObjectMapper.serializeObject(ObjectMapper.java:517)
>         at org.elasticsearch.index.mapper.object.ObjectMapper.parse(ObjectMapper.java:459)
>         at org.elasticsearch.index.mapper.object.ObjectMapper.serializeObject(ObjectMapper.java:517)
>         at org.elasticsearch.index.mapper.object.ObjectMapper.parse(ObjectMapper.java:459)
>         at org.elasticsearch.index.mapper.DocumentMapper.parse(DocumentMapper.java:515)
>         at org.elasticsearch.index.mapper.DocumentMapper.parse(DocumentMapper.java:462)
>         at org.elasticsearch.index.shard.service.InternalIndexShard.prepareCreate(InternalIndexShard.java:363)
>         at org.elasticsearch.action.index.TransportIndexAction.shardOperationOnPrimary(TransportIndexAction.java:215)
>         at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$AsyncShardOperationAction.performOnPrimary(TransportShardReplicationOperationAction.java:556)
>         at org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction$AsyncShardOperationAction$1.run(TransportShardReplicationOperationAction.java:426)
>         at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>         at java.lang.Thread.run(Thread.java:662)
>     Caused by: org.elasticsearch.ElasticsearchIllegalArgumentException: unknown property [propertyFromProperty2]
>         at org.elasticsearch.index.mapper.core.StringFieldMapper.parseCreateFieldForString(StringFieldMapper.java:331)
>         at org.elasticsearch.index.mapper.core.StringFieldMapper.parseCreateField(StringFieldMapper.java:277)
>         at org.elasticsearch.index.mapper.core.AbstractFieldMapper.parse(AbstractFieldMapper.java:408)

what are my options here? I though maybe to use the field type with the name in order to avoid parsing errors, is this possible using elasticsearch?

Is there another solution therefore?


(David Pilato) #2

The same field can not be either a String or an Object.
Change property2 in one of your classes to another name so it won't conflict.

BTW if you are doing inheritance, property2 should be defined in the parent class as it seems to be a "common" property, right?


(Spaeth) #3

Thanks for the suggestion. This would solve the problem, but was hoping to get a solution in which a model change wouldn't really be necessary (because it isn't over my power to change it).

At the end I applied something quite similar, I converted each value to an object, and simple values (like string, ints longs, floats and so on...) are represented by an object with one property (in my case I named it __VALUE__, it is true that from that moment on, __VALUE__ can't be used to name properties, but this name goes against the convention we use anyways.

So, with this approach if any field that is a string (represented by an object with one property, __VALUE__, in this case) needs to be written as object for an specific document it will not have any type conflict (as it is already an object).


(system) #4