Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XContentBuilder Elasticsearch mapping for inner objects

I am trying to create a mapping for documents of the following structure:

"name":"Peter"
"id":"ABC123",  
"values":{
    "a":3.0123,        
    "b":1234
}

So the mapping should look like this:

{
 "properties":{"_all":{"enabled":"false"},
 "dynamic":"false",
 "_timestamp":{"enabled":true,"store":true},
 "properties": {
     "name":{"type":"string"},
     "id":{"type":"string"},
     "values": {
         "properties": {
              "a": {"type":"double"},
              "b":{"type":"double"}
          }
     }
   } 
  }
}

In reality the amount of possible properties in "values" is quite big, let's say 50 possible properties I have to include there..

I am currently generating the mapping json with the XContentBuilder, which works really fine for me.

What I want to do is, encapsulating the inner part's mapping in "values" in a seperate builder, as it makes the process of mapping easier to maintain for me. Also I already have the inner properties' names in a list, which I'd like to iterate.

Thats my normal mapping code here.

XContentBuilder xbMapping = jsonBuilder()
            .startObject() // start root
                .startObject(PROPERTIES)
                    .startObject("_all").field("enabled", "false").endObject()
                    .field("dynamic", "false")
                    .startObject("_timestamp").field("enabled", true).field("store", true).endObject()
                    .startObject(PROPERTIES)
                        .startObject("name").field("type", "string").endObject()
                        .startObject("id").field("type", "string").endObject()
                        .startObject("values")
                            .startObject(PROPERTIES)
                                 // INNER MAPPING HERE!!
                            .endObject()
                        .endObject()
                .endObject()
            .endObject();

I'd like to avoid iterating in between those startObject and endObject and more like to do the complete mapping for the inner type somewhere else and just include that extra part there.

I can't find a sophisticated way at the moment with XContentBuilder.

Thanks for any hints

like image 562
skombijohn Avatar asked Jan 13 '14 10:01

skombijohn


1 Answers

The XContentBuilder is mutated with every method call, the builder pattern is just for convenience. So you can interrupt the chained calls anytime

private void buildValues(XContentBuilder builder) throws IOException {
    String[] values = {"a", "b"};
    for (String value : values) {
        builder.startObject(value).field("type", "double").endObject();
    }
}


XContentBuilder xbMapping = jsonBuilder()
        .startObject() // start root
            .startObject(PROPERTIES)
                .startObject("_all").field("enabled", "false").endObject()
                .field("dynamic", "false")
                .startObject("_timestamp").field("enabled", true).field("store", true).endObject()
                .startObject(PROPERTIES)
                    .startObject("name").field("type", "string").endObject()
                    .startObject("id").field("type", "string").endObject()
                    .startObject("values")
                        .startObject(PROPERTIES);

buildValues(xbMapping);

xbMapping
                        .endObject()
                    .endObject()
            .endObject()
        .endObject();
like image 178
knutwalker Avatar answered Nov 04 '22 00:11

knutwalker