Chennai Cheetah
Chennai Cheetah

Reputation: 363

Grouping by Unique ID for JSON Array

Blockquote

I have below JSON Input Request which has to be group by ID parameter.

Input :

[
    {
        "ID": "1234",
        "CustomerName": "KUMAR",
        "BranchName": "HARBOUR",
        "SchemeName": "GOLD",
        "MobileNumber": "123456789",
        "CustomerType": "PRIMARY",
        "DedupeFound" : "NO"
        
    },
    {
        "ID": "1234",
        "CustomerName": "SEAN",
        "BranchName": "HARBOUR",
        "SchemeName": "GOLD",
        "MobileNumber": "123456789",
        "CustomerType": "SECONDARY",
        "DedupeFound" : "YES"
    },
    {
        "ID": "5678",
        "CustomerName": "MARK",
        "BranchName": "CANTONMENT",
        "SchemeName": "DIAMOND",
        "MobileNumber": "123456789",
        "CustomerType": "PRIMARY",
        "DedupeFound" : "NO"
    },
    {
        "ID": "5678",
        "CustomerName": "STEVE",
        "BranchName": "CANTONMENT",
        "SchemeName": "DIAMOND",
        "MobileNumber": "123456789",
        "CustomerType": "SECONDARY",
        "DedupeFound" : "YES"
    }
]

The above request needs to be transformed in the below way

  1. First records to be grouped based on ID Tag and only primary ID's details needs to be displayed
  2. Inside the ID Record details . I have an DedupeDetails Array for both the customers.

Output

[
    {
        "ID": "1234",
        "CustomerName": "KUMAR",           // Only Primary Customer Details for the 
        "BranchName": "HARBOUR",           //  ID Tag to be displayed here
        "SchemeName": "GOLD",
        "MobileNumber": "123456789"
        "DedupeDetails": [
            {
                "CustomerType": "PRIMARY"
                "CustomerName": "KUMAR",
                "DedupeFound" : "NO"
            },
            {
                "CustomerType": "SECONDARY"
                "CustomerName": "SEAN",
                "DedupeFound" : "YES"
            }
        ]
    },
    {
        "ID": "5678",
        "CustomerName": "MARK",
        "BranchName": "CANTONMENT",
        "SchemeName": "DIAMOND",
        "MobileNumber": "123456789"
        "DedupeDetails": [
            {
                "CustomerType": "PRIMARY"
                "CustomerName": "MARK",
                "DedupeFound" : "NO"
            },
            {
                "CustomerType": "SECONDARY"
                "CustomerName": "STEVE",
                "DedupeFound" : "YES"
            }
        ]
    }
]

I have started with the java code in apache camel . where I am able to map json string to Object List successfully. I am still clueless on how to do grouping to achieve the output.

Note : I am a newbie to java . Any Suggestions / Corrections are highly recommended.

Java

package com.mycompany.Login;

import java.util.List;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.sql.Timestamp;
import java.io.File;
import java.io.PrintWriter;
import java.sql.Time;
import com.mycompany.Login.*;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mycompany.Dedupe.DedupeRoot.DedupeRes;




public class LoginMapping implements Processor{
    public void process(Exchange ex)throws Exception{ 
    
        try {   
        
           
            String responseString = {Input mentioned in post};          
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);         
            List<DedupeRes> dedupe = Arrays.asList(mapper.readValue(responseString, DedupeRes[].class));  
            int total = dedupe.size();          
            if (total > 0)
            {               
                for (int i = 0; i < total; i++) {                   
                    
                }               
            }
    
     ex.getIn().setBody(responseString);
        }       
        catch(Exception e) {
            ex.getIn().setHeader("ExpMsg", "Undefined");
            throw e;
        }   
    
}
}

Upvotes: 0

Views: 596

Answers (3)

Raymond Choi
Raymond Choi

Reputation: 1271

You can use JSON library such as Josson to do the transformation.

https://github.com/octomix/josson

Deserialization

Josson josson = Josson.fromJsonString(yourJsonString);

Method 1

Find the primary record of each group from the root node.

JsonNode node = josson.getNode(
    "group(ID, DedupeDetails:map(CustomerType, CustomerName, DedupeFound))@" +
    ".let($id:ID, $pri:$.[ID=$id & CustomerType='PRIMARY'])" +
    ".field($pri.CustomerName, $pri.BranchName, $pri.SchemeName, $pri.MobileNumber)");

System.out.println(node.toPrettyString());

Method 2

Find the primary record within each group.

JsonNode node = josson.getNode(
    "group(ID)@" +
    ".let($pri: elements[CustomerType='PRIMARY'])" +
    ".field($pri.CustomerName, $pri.BranchName, $pri.SchemeName, $pri.MobileNumber," +
    "       elements:, DedupeDetails:elements.map(CustomerType, CustomerName, DedupeFound))");

System.out.println(node.toPrettyString());

Method 3

Use mergeObjects() instead of let() to do the task.

JsonNode node = josson.getNode(
    "group(ID)@" +
    ".mergeObjects(" +
    "  elements[CustomerType='PRIMARY'].map(ID, CustomerName, BranchName, SchemeName, MobileNumber)," +
    "  map(DedupeDetails:elements.map(CustomerType, CustomerName, DedupeFound))" +
    ")");

System.out.println(node.toPrettyString());

Upvotes: 0

hani
hani

Reputation: 51

First you must create DedupeDetail class:

public class DedupeDetail {

    String CustomerType;
    String CustomerName;
    String DedupeFound;

    public DedupeDetail(String customerType, String customerName, String dedupeFound) {
        CustomerType = customerType;
        CustomerName = customerName;
        DedupeFound = dedupeFound;
    }
}

Then create DedupeResultFinal with converter:

public class DedupeResultFinal {

    String ID;
    String CustomerName;
    String BranchName;
    String SchemeName;
    String MobileNumber;
    List<DedupeDetail> DedupeDetails;

    public DedupeResultFinal() {
    }

    public DedupeResultFinal(List<DedupeDetail> dedupeDetails) {
        DedupeDetails = dedupeDetails;
    }// ... other constructor and getter and setter

    public static DedupeResultFinal convertToFinal(HashMap<String, String> dedupeRes){
        DedupeResultFinal dedupeResultFinal = new DedupeResultFinal();

        dedupeResultFinal.setBranchName(dedupeRes.get("BranchName"));
        dedupeResultFinal.setCustomerName(dedupeRes.get("CustomerName"));
        dedupeResultFinal.setID(dedupeRes.get("ID"));
        dedupeResultFinal.setMobileNumber(dedupeRes.get("MobileNumber"));
        dedupeResultFinal.setSchemeName(dedupeRes.get("SchemeName"));

        return dedupeResultFinal;

    }
}

And then your method must be like this:

   public static void main(String[] args) {
        try {

            String responseString = {Input mentioned in post};
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            List<HashMap<String, String>> dedupe = mapper.readValue(responseString, new ArrayList<String>().getClass());
            Map<String, DedupeResultFinal> map = new HashMap<>();

            for (HashMap<String, String> dedupeRes : dedupe) {
                if (map.get(dedupeRes.get("ID")) != null){
                    DedupeDetail dedupeDetail = new DedupeDetail(dedupeRes.get("CustomerType"), dedupeRes.get("CustomerName"), dedupeRes.get("DedupeFound"));
                    map.get(dedupeRes.get("ID")).getDedupeDetails().add(dedupeDetail);
                }else {
                    DedupeDetail dedupeDetail =  new DedupeDetail(dedupeRes.get("CustomerType"), dedupeRes.get("CustomerName"), dedupeRes.get("DedupeFound"));
                    DedupeResultFinal dedupeResultFinal = DedupeResultFinal.convertToFinal(dedupeRes);
                    List<DedupeDetail> dedupeDetails = new ArrayList<>();
                    dedupeDetails.add(dedupeDetail);
                    dedupeResultFinal.setDedupeDetails(dedupeDetails);

                    map.put(dedupeRes.get("ID"), dedupeResultFinal);
                }
            }

           List<DedupeResultFinal> finalDedup = map.values().stream().collect(Collectors.toList());

            System.out.println(finalDedup);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

Upvotes: 1

rongfeiyue
rongfeiyue

Reputation: 149

Complete code implementation, try it.

public class T {

    private static final ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public static <T> List<T> parseObjectList(String json, Class<T> clazz) {
        try {
            return mapper.readValue(
                    json,
                    TypeFactory.defaultInstance().constructParametricType(ArrayList.class, clazz)
            );
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> String toJsonString(T t) {
        try {
            return mapper.writeValueAsString(t);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        try {
            String responseString = "[{\"ID\":\"1234\",\"CustomerName\":\"KUMAR\",\"BranchName\":\"HARBOUR\",\"SchemeName\":\"GOLD\",\"MobileNumber\":\"123456789\",\"CustomerType\":\"PRIMARY\",\"DedupeFound\":\"NO\"},{\"ID\":\"1234\",\"CustomerName\":\"SEAN\",\"BranchName\":\"HARBOUR\",\"SchemeName\":\"GOLD\",\"MobileNumber\":\"123456789\",\"CustomerType\":\"SECONDARY\",\"DedupeFound\":\"YES\"},{\"ID\":\"5678\",\"CustomerName\":\"MARK\",\"BranchName\":\"CANTONMENT\",\"SchemeName\":\"DIAMOND\",\"MobileNumber\":\"123456789\",\"CustomerType\":\"PRIMARY\",\"DedupeFound\":\"NO\"},{\"ID\":\"5678\",\"CustomerName\":\"STEVE\",\"BranchName\":\"CANTONMENT\",\"SchemeName\":\"DIAMOND\",\"MobileNumber\":\"123456789\",\"CustomerType\":\"SECONDARY\",\"DedupeFound\":\"YES\"}]";
            List<DedupeRes> list = parseObjectList(responseString, DedupeRes.class);
            if (list != null && !list.isEmpty()) {
                Map<String, List<DedupeRes>> map = list.stream().collect(Collectors.groupingBy(DedupeRes::getID));
                List<Res> resList = new ArrayList<>();
                map.forEach((k, v) -> resList.add(listToRes(v)));
                responseString = toJsonString(resList);
                System.out.println(responseString);
            }
        } catch (Exception e) {
            // xx
            e.printStackTrace();
        }
    }

    private static Res listToRes(List<DedupeRes> list) {
        Res res = new Res();
        res.setDedupeDetails(new ArrayList<>());
        for (DedupeRes dedupeRes : list) {
            if (Objects.equals("PRIMARY", dedupeRes.getCustomerType())) {
                // if you used spring -> BeanUtils.copyProperties(dedupeRes, res);
                res.setID(dedupeRes.getID());
                res.setBranchName(dedupeRes.getBranchName());
                res.setCustomerName(dedupeRes.getCustomerName());
                res.setMobileNumber(dedupeRes.getMobileNumber());
                res.setSchemeName(dedupeRes.getSchemeName());
            }
            DedupeDetails details = new DedupeDetails();
            //
            BeanUtils.copyProperties(dedupeRes, details);
            res.getDedupeDetails().add(details);
        }
        return res;
    }

    @Data
    private static class DedupeRes {
        @JsonProperty("ID")
        private String ID;
        @JsonProperty("CustomerName")
        private String CustomerName;
        @JsonProperty("BranchName")
        private String BranchName;
        @JsonProperty("SchemeName")
        private String SchemeName;
        @JsonProperty("MobileNumber")
        private String MobileNumber;
        @JsonProperty("CustomerType")
        private String CustomerType;
        @JsonProperty("DedupeFound")
        private String DedupeFound;
    }

    @Data
    private static class Res {
        @JsonProperty("ID")
        private String ID;
        @JsonProperty("CustomerName")
        private String CustomerName;
        @JsonProperty("BranchName")
        private String BranchName;
        @JsonProperty("SchemeName")
        private String SchemeName;
        @JsonProperty("MobileNumber")
        private String MobileNumber;
        @JsonProperty("dedupeDetails")
        private List<DedupeDetails> dedupeDetails;
    }

    @Data
    private static class DedupeDetails {
        @JsonProperty("CustomerType")
        private String CustomerType;
        @JsonProperty("CustomerName")
        private String CustomerName;
        @JsonProperty("DedupeFound")
        private String DedupeFound;
    }
}

consule.

[{"ID":"1234","CustomerName":"KUMAR","BranchName":"HARBOUR","SchemeName":"GOLD","MobileNumber":"123456789","dedupeDetails":[{"CustomerType":"PRIMARY","CustomerName":"KUMAR","DedupeFound":"NO"},{"CustomerType":"SECONDARY","CustomerName":"SEAN","DedupeFound":"YES"}]},{"ID":"5678","CustomerName":"MARK","BranchName":"CANTONMENT","SchemeName":"DIAMOND","MobileNumber":"123456789","dedupeDetails":[{"CustomerType":"PRIMARY","CustomerName":"MARK","DedupeFound":"NO"},{"CustomerType":"SECONDARY","CustomerName":"STEVE","DedupeFound":"YES"}]}]

Upvotes: 1

Related Questions