How do you combine multiple JSON strings into one ( Java ) - java

I tried searching for a JAVA library that I could use but to no avail.
Is there a gson/jackson/groovy library I could use to combine or merge together multiple JSON Strings into one payload?
Example :
JSON payload A, B and C
I would like both B and C to be added/merged to A.
Also removing any duplicated keys that are null or empty.
Example :
First JSON :
{
"businessUnitHierarchies":[
{
"actionType":"sample123",
"businessUnitHierarchy":{
"businessUnit":"sample123"
}
}
],
"description":{
"EN":"description sample",
"FR":"sample de description"
},
"name":{
"EN":"Coupon by a bot",
"FR":"Coupon par un bot"
},
"discountType":"Cost+",
"quantity":0,
"usageType":"shared",
"notes":"sample notes",
"discounts":[
{
"discountLevel":"SAMPLE",
"discountAmount":"10"
}
],
"couponId":0
}
Second JSON :
{
"effectiveDate":"2020-09-10",
"expiryDate":"2020-09-11",
"quantity":0,
"couponId":0
}
Third JSON
{
"productHierarchies":[
{
"productHierarchy":{
"level":7
},
"businessUnit":"fgl",
"actionType":"include",
"brand":"SAMPLE",
"discountAmount":"35"
}
],
"quantity":0,
"couponId":0
}
My desired output is :
Desired Output :
{
"businessUnitHierarchies":[
{
"actionType":"sample123",
"businessUnitHierarchy":{
"businessUnit":"sample123"
}
}
],
"description":{
"EN":"description sample",
"FR":"sample de description"
},
"name":{
"EN":"Coupon by a bot",
"FR":"Coupon par un bot"
},
"discountType":"Cost+",
"quantity":0,
"usageType":"shared",
"notes":"sample notes",
"discounts":[
{
"discountLevel":"SAMPLE",
"discountAmount":"10"
}
],
"couponId":0,
"effectiveDate":"2020-09-10",
"expiryDate":"2020-09-11",
"quantity":0,
"productHierarchies":[
{
"productHierarchy":{
"level":7
},
"businessUnit":"fgl",
"actionType":"include",
"brand":"SAMPLE",
"discountAmount":"35"
}
]
}

Wouldn't this be all you want? Based on Gson.
void merge(JsonObject dest, JsonObject src) {
for (var entry : src.entrySet()) {
dest.add(entry.getKey(), entry.getValue();
}
}

Related

How to assign to a new array an array of objects?

I can't figure out how I would do the ff.
I have the ff. Payload
{
"code": null,
"message": null,
"recCtrlOut": {
},
"acctSumm": [
{
"acctBasic": {
"acctType": "SV",
"acctId": "123",
},
"acctBasic": {
"acctType": "SV",
"acctId": "321",
}
}
]
}
And I just want to get the acctId params and assign it to a new plain array of accountIds. How do I do it in Spring/Java?. Thanks
Try using json path. Library can be found here. E.g. say you had json like this:
{
"code": null,
"message": null,
"recCtrlOut": {
},
"acctSumm": [
{
"acctBasic": {
"acctType": "SV",
"acctId": "123"
}
},
{
"acctBasic": {
"acctType": "SV",
"acctId": "321"
}
}
]
}
Actual code would be something like:
List<String> ids = JsonPath.read(json, "$.acctSumm[*].acctBasic.acctId");
The above list will now hold:
["123","321"]
If you wanna learn json path syntax, you could try using this online tool. Here is also a guide to help you get started with json path.

How to get path for child in Array[String] returned by Jayway

I have nested json data, like so:
{
"libraries":[
{
"State":"California",
"genres":[
{
"genre":"thriller",
"books":[
{
"title":"Book 1"
},
{
"title":"Book 2"
}
]
},
{
"genre":"mystery",
"books":[
{
"title":"Book 2"
},
{
"title":"Book 3"
}
]
}
]
},
{
"State":"New York",
"genres":[
{
"genre":"horror",
"books":[
{
"title":"Book 2"
},
{
"title":"Book 5"
}
]
},
{
"genre":"comedy",
"books":[
{
"title":"Book 6"
},
{
"title":"Book 7"
}
]
}
]
}
]
}
And I am using the jayway jsonpath library in Scala to parse it.
I could use something like JsonPath.read(myData,"$.libraries[*].genres[*].books[*]") to get an array of all the books pooled from every library. What I want is to know the path for each book, e.g. "$.libraries(0).genres(1).books(0)". Is there a ways to get an array of all the book paths rather than just all the books?
I am new to jsonpaths in general, so forgive me if this is not a good question.
You can use configuration with Option.AS_PATH_LIST:
val conf = Configuration.builder.options(Option.AS_PATH_LIST).build
val paths = JsonPath.parse(json, conf).read[JSONArray]("$.libraries[*].genres[*].books[*]")
for(path <- paths.toArray){
println(path.toString)
}
Which gives in case of your example json:
$['libraries'][0]['genres'][0]['books'][0]
$['libraries'][0]['genres'][0]['books'][1]
$['libraries'][0]['genres'][1]['books'][0]
$['libraries'][0]['genres'][1]['books'][1]
$['libraries'][1]['genres'][0]['books'][0]
$['libraries'][1]['genres'][0]['books'][1]
$['libraries'][1]['genres'][1]['books'][0]
$['libraries'][1]['genres'][1]['books'][1]

Getting multiple field group by result in elasticserach using java api

I have a json
{"id": 2,"name": "Chethan","address":"Banglore"}
Trying to groupby two fields id and name,
List<String> statFields = new ArrayList();
statFields.add("name");
statFields.add("id");
// 2. bootstrap the query
SearchRequestBuilder search = client.prepareSearch("student")
.setSize(0).setFrom(0)
.setQuery(QueryBuilders.matchAllQuery());
// 3. add a stats aggregation for each of your fields
for (String field : statFields) {
search.addAggregation(AggregationBuilders.terms(field+"_stats").field(field));
}
// 4. execute the query
SearchResponse response = search.execute().actionGet();
for(String field : statFields) {
Terms termAgg = (Terms) response.getAggregations().get(field+"_stats");
for (Terms.Bucket entry : termAgg.getBuckets()) {
System.out.println(entry.getKey() + " **** " + entry.getDocCount()); // Doc count
}
}
Below is the response
chethan**** 2
Raj**** 1
Mohan**** 1
1 **** 1
2 **** 1
3 **** 1
But I need combined response like sql,
name id count
chethan 1 1
is it possible through elasticsearch java api
You should have used subAggregation plus use keyword type for aggregations.
Java Rest High-Level Client
Assuming your mappings look like:
PUT student
{
"mappings": {
"doc": {
"properties": {
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"id": {
"type": "keyword"
},
"address": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
}
In order to group by name and id you should use this query (low level query):
GET student/_search
{
"size": 0,
"aggs": {
"name": {
"terms": {
"field": "name.keyword",
"size": 10
},"aggs": {
"id": {
"terms": {
"field": "id",
"size": 10
}
}
}
}
}
}
In java the query above is similar to:
SearchResponse response = client.search(new SearchRequest("student")
.source(new SearchSourceBuilder()
.size(0)
.aggregation(
AggregationBuilders.terms("by_name").field("name.keyword")
.subAggregation(AggregationBuilders.terms("by_id")
.field("id")
)
);
If you want to use your code, probably something like that :
// 2. bootstrap the query
SearchRequestBuilder search = client.prepareSearch("student")
.setSize(0).setFrom(0)
.setQuery(QueryBuilders.matchAllQuery());
// 3. add a stats aggregation for each of your fields
TermsAggregationBuilder aggregation = AggregationBuilders.terms("name_stats").field("name.keyword");
aggregation.subAggregation(AggregationBuilders.terms("id_stats").field("id"));
search.aggregation(aggregation);
// 4. execute the query
SearchResponse response = search.execute().actionGet();
Terms termAgg = (Terms)response.getAggregations().get("name_stats");
for (Terms.Bucket entry: termAgg.getBuckets()) {
if (entry.getDocCount() != 0) {
Terms terms =entry.getAggregations().get("id");
Collection<Terms.Bucket> buckets = terms.getBuckets();
for (Bucket sub : buckets ) {
System.out.println((int) sub.getDocCount());
System.out.println(sub.getKeyAsString());
}
}
}
I removed the for loop. you should design your own structure now that you have to use sub-aggregations.
UPDATE
Is this what you want?
GET student/_search
{
"size": 0,
"aggs" : {
"name_id" : {
"terms" : {
"script" : {
"source": "doc['name.keyword'].value + '_' + doc['id'].value",
"lang": "painless"
}
}
}
}
}
I hope this is what you aimed for.

How to construct the JsonPath from soapui Json Response using groovy?

I have an soapui response like below and i tried to parse the same and print all the elements(From leaf node) in the json response.
Sample Json :
{
"BookID": 7982,
"author": {
"authorname": "roboin"
},
"authorid": "X-1-23",
"BookDetails": [{
"Price": "100",
"Location": "Paris"
}],
"authordob": "1980-11-10",
"Adverts": {
"online": true
}
}
Use of below groovy script is to print all the elements in the response.The below code goes to each and every element in the Json response and print like below Expected Result,
Expected Result: Print all the element(leaf node) jsonpath and values
$.['author']['authorname'] : roboin
$.['BookDetails'][0]['Price']:100
Current Result : Prints all the elements and values
authorname : roboin
Price:100
import groovy.json.*
//Get the test case response from context and parse it
def contextResponse = messageExchange.getResponseContent().toString()
//log.info(contextResponse)
def parseResponse = new JsonSlurper().parseText(contextResponse)
//log.info(parseResponse)
def parseMap(map) {
map.each {
if (it.value instanceof Map) {
parseMap(it.value)
} else if (it.value instanceof List) {
log.info(it.key + ": ")
parseArray(it.value)
} else {
log.info(it.key + ": " + it.value)
}
}
}
def parseArray(array) {
array.each {
if (it instanceof Map) {
parseMap(it)
} else if (it instanceof List) {
parseArray(it)
} else {
log.info("arrayValue: $it");
}
}
}
parseMap(parseResponse)
I tried some research about this and found few json path selector in online and that can't be used inside my soapui application.i want to iterate and print all the elements json path and their values.
Currently the above code iterate and prints only the element name and values.
def j=new groovy.json.JsonSlurper().parseText('''{
"BookID": 7982,
"author": {
"authorname": "roboin"
},
"authorid": "X-1-23",
"BookDetails": [{
"Price": "100",
"Location": "Paris"
}],
"authordob": "1980-11-10",
"Adverts": {
"online": true
}
}''')
void printJsonPaths(o, path='$'){
if(o instanceof Map){
o.each{ k,v-> printJsonPaths(v, path+"['${k}']") }
}else if(o instanceof List){
o.eachWithIndex{ v,i-> printJsonPaths(v, path+"[${i}]") }
}else{
println("${path}: ${o}")
}
}
printJsonPaths(j)
output
$['BookID']: 7982
$['author']['authorname']: roboin
$['authorid']: X-1-23
$['BookDetails'][0]['Price']: 100
$['BookDetails'][0]['Location']: Paris
$['authordob']: 1980-11-10
$['Adverts']['online']: true

get value from a JSONObject

I have a JSONObject.
{
"_shards":{
"total":251,
"failed":0,
"successful":251
},
"hits":{
"hits":[
],
"total":7775532,
"max_score":0
},
"took":517,
"timed_out":false,
"facets":{
"terms":{
"total":2287,
"other":0,
"terms":[
{
"count":2268,
"term":"contact"
},
{
"count":19,
"term":""
}
],
"_type":"terms",
"missing":424
}
}
}
I want to get the value of hits.total which here is 7775532.
How can I get that ? Is there some function that can help ? I am using Java
jsonObject.getJSONObject("hits").get("total")

Categories

Resources