cancel
Showing results forย 
Search instead forย 
Did you mean:ย 

Defining Schemas with Arrays?

rpatrick00
Contributor

Can someone please explain the proper way to define and work schemas containing arrays of primitive types and of complex objects?

The SnapType.TABLE seems to be the correct SnapType but it seems that the approach that works for complex objects does not work for primitive types (and vice versa). How is this supposed to be done?

1 REPLY 1

rpatrick00
Contributor

So it seems that no one knows the answer so I thought I would share what I have that seems to work properly. Take data that looks like this:

{
    "Comment" : [  "comment1", "comment2" ],
    "Names": [
        {
            "First": "John",
            "Last": "Lennon"
        },
        {
            "First": "Paul",
            "Last": "McCartney"
        }
    ]
}

With both cases, the solution has an unnamed schema that must be a child of the TABLE schema in order for the upstream Mapper to display the target schema properly.

For the Comment schema, the unnamed child schema is used to specify that the schema is a list of Strings:

ObjectSchema commentSchema = schemaProvider.createSchema(SnapType.TABLE, "Comment");
commentSchema.addChild(schemaProvider.createSchema(SnapType.STRING, ""));

For the Names schema, the unnamed child schema is used to hold the attributes of each of the objects:

ObjectSchema arraySchema = schemaProvider.createSchema();
arraySchema.addChild(schemaProvider.createSchema(SnapType.STRING, "First");
arraySchema.addChild(schemaProvider.createSchema(SnapType.STRING, "Last");
ObjectSchema namesSchema  = schemaProvider.createSchema(SnapType.TABLE, "Names");
namesSchema.addChild(arraySchema);

When receiving the data from SnapLogic, the data types of the underlying objects are exactly what you would expect (if you ignore the unnamed child schema). For example, the items in the names list is a map containing the keys First and Last.

@Override
public void process(Document document) {
    @SuppressWarnings("unchecked")
    Map<String, Object> inputData = document.get((Class<Map<String, Object>>) (Class<?>) Map.class);

    @SuppressWarnings("unchecked")
    List<String> commentList = (List<String>) inputData.get("Comment");

    @SuppressWarnings("unchecked")
    List<Map<String, Object>> namesList = (List<Map<String, Object>>) inputData.get("Names");
    
    ...
}

Hope this helps save others the time it took experimenting with this to figure it out.
Robert