I need a mongo DB query as well as corresponding java code for the query using aggregation framework for the below mentioned scenario,
Scenario is :
I need to search an array for "seqNo": 4 based on "aC","aI","aN","aT","bID","pD" from collection A.
Please find the collection mentioned below,
Collection A:
/*1*/
{
"_id" : ObjectId("6398b904aa0c28d6193bb853"),
"aC" : "AB",
"aI" : "ABCD",
"aN" : "040000000002",
"aT" : "CA",
"bID" : NumberLong(0),
"pD" : "2019-04-19",
"timeToLive" : ISODate("2019-04-19T00:00:00.000Z"),
"transactions" : [
{
"amt" : NumberDecimal("-12.340"),
"seqNo" : 2,
"valDt" : "2022-10-04"
},
{
"amt" : NumberDecimal("-6.800"),
"seqNo" : 5,
"valDt" : "2022-10-04"
}
]
}
/*2*/
{
"_id" : ObjectId("5d42daa7decf182710080d46"),
"aC" : "AB",
"aI" : "ABCD",
"aN" : "040000000002",
"aT" : "CA",
"bID" : NumberLong(1),
"pD" : "2019-04-19",
"timeToLive" : ISODate("2019-04-19T00:00:00.000Z"),
"transactions" : [
{
"seqNo" : 4,
"amt" : NumberDecimal("26074.000"),
"valDt" : "2019-04-19"
},
{
"seqNo" : 3,
"amt" : NumberDecimal("26074.000"),
"valDt" : "2019-04-19"
}
]
}
Please help me with the query it will be really helpful if explained in detail.
Thanks in advance.
To kick off the answer we will start with the mongo CLI (javascript) because it outlines what we are going to do later in Java.
db.foo.aggregate([
{$match: {"aC": val_aC, "aI": val_aI}},
{$project: {transaction: {$arrayElemAt: [ {$filter: {
input: "$transactions",
cond: {$eq:["$$this.seqNo",4]}
}}, 0] }
}},
{$match: {transaction: {$exists: true}}}
]);
Java is always a little more verbose than python or javascript but here is how I do it. Because my editor matches braces and brackets, I find it easier to construct the query as JSON and then convert it into the required pipeline of Document objects.
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.AggregateIterable;
import org.bson.*;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.HashMap;
import java.math.BigDecimal;
public class agg4 {
private MongoClient mongoClient;
private MongoDatabase db;
private MongoCollection<Document> coll;
private static class StageHelper {
private StringBuilder txt;
public StageHelper() {
this.txt = new StringBuilder();
}
public void add(String expr, Object ... subs) {
expr.replace("'", "\""); // This is the helpful part.
if(subs.length > 0) {
expr = String.format(expr, subs); // this too
}
txt.append(expr);
}
public Document fetch() {
return Document.parse(txt.toString());
}
}
private List<Document> makePipeline() {
List<Document> pipeline = new ArrayList<Document>();
StageHelper s = new StageHelper();
// It is left as an exercise to add all the other individual fields
// that need to be matched and properly pass them in, etc.
String val_aC = "AB";
String val_aI = "ABCD";
s.add(" {'$match': {'aC':'%s','aI':'%s'}}", val_aC, val_aI );
pipeline.add(s.fetch());
s = new StageHelper();
// This is the meat. Find seqNo = 4. Since I suspect seqNo is
// unique, it does no extra good to filter the array to just an array
// array of one; changing the array of 1 (if found of course) to a
// *single* object has more utility, hence use of $arrayElemAt:
s.add(" {'$project': {'transaction': {'$arrayElemAt': [ ");
s.add(" {'$filter': {'input': '$transactions', ");
s.add(" 'cond': {'$eq':['$$this.seqNo', 4]} ");
s.add(" }}, 0]} ");
s.add(" }}");
pipeline.add(s.fetch());
s = new StageHelper();
// If seqNo = 4 could not be found, transaction will be unset so
// use the following to exclude that doc.
s.add(" {'$match': {'transaction': {'$exists': true}}} ");
pipeline.add(s.fetch());
return pipeline;
}
private void doAgg() {
try {
List<Document> pipeline = makePipeline();
AggregateIterable<Document> output = coll.aggregate(pipeline);
MongoCursor<Document> iterator = output.iterator();
while (iterator.hasNext()) {
Document doc = iterator.next();
}
} catch(Exception e) {
System.out.println("some fail: " + e);
}
}
public static void main(String[] args) {
(new agg4()).go(args);
}
public void go(String[] args) {
try {
Map params = new HashMap();
String host = "mongodb://localhost:37017/?replicaSet=rs0";
String dbname = "testX";
String collname = "foo";
mongoClient = MongoClients.create(host);
db = mongoClient.getDatabase(dbname);
coll = db.getCollection(collname, Document.class);
doAgg();
} catch(Exception e) {
System.out.println("epic fail: " + e);
e.printStackTrace();
}
}
If you are using Java 13 or higher, text blocks for String make it even easier:
String s = """
{'$project': {'transaction': {'$arrayElemAt': [
{'$filter': {'input': '$transactions',
'cond': {'$eq':['$$this.seqNo', 4]}
}}, 0]}
}}
""";
pipeline.add(s.fetch());
Related
I have created a minimal application in order to debug the following problem:
The application is creating a Java object which includes a GeoJsonPoint. When the object gets validated against an automatically created json schema, I receive different results when starting the application multiple times. For example, I am starting the application for 5 times and the result is "Json not valid!". When I start the application another time, I receive the result "Json successfully validated".
The error message when the json is not valid tells me:
/geoPosition/coordinates: instance type (array) does not match any allowed primitive type (allowed: [object])
The following line is randomly returning a different json schema:
JsonNode fstabSchema = schemaFactory.createSchema(inputObj.getClass());
I do not understand that this happens randomly. Has someone seen this behavior before?
To exclude dependency problems during runtime, I have created a jar with all dependencies (jar-with-dependencies)
Below are my files:
pom.xml dependencies:
<dependencies>
<dependency>
<groupId>com.github.reinert</groupId>
<artifactId>jjschema</artifactId>
<version>1.16</version>
</dependency>
<dependency>
<groupId>com.github.java-json-tools</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.2.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>1.18.16</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>3.2.2</version>
</dependency>
</dependencies>
App.java:
package de.s2.json.test;
import java.util.ArrayList;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
public class App
{
public static void main( String[] args )
{
Address address = new Address();
address.setCountry("Deutschland");
GeoJsonPoint geoPoint = new GeoJsonPoint(12, 23);
address.setGeoPosition(geoPoint);
ArrayList<String> ret = null;
try {
ret = Toolbox.validateJson(address);
} catch (ProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(ret != null) {
System.out.println("Json not valid!");
for (int i = 0; i < ret.size(); i++) {
System.out.println(ret.get(i));
}
} else {
System.out.println("Json successfully validated");
}
}
}
Toolbox.java:
package de.s2.json.test;
import java.util.ArrayList;
import java.util.Iterator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.reinert.jjschema.v1.JsonSchemaV4Factory;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import com.github.fge.jsonschema.core.report.ProcessingMessage;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
public class Toolbox {
public static <T> ArrayList<String> validateJson(T inputObj) throws ProcessingException {
com.github.reinert.jjschema.v1.JsonSchemaFactory schemaFactory = new JsonSchemaV4Factory();
schemaFactory.setAutoPutDollarSchema(true);
JsonNode fstabSchema = schemaFactory.createSchema(inputObj.getClass()); // <= here I get different results
final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
final JsonSchema schema = factory.getJsonSchema(fstabSchema);
ObjectMapper objectMapper = new ObjectMapper();
JsonNode baseReceiptJson = objectMapper.convertValue(inputObj, JsonNode.class);
ProcessingReport report;
report = schema.validate(baseReceiptJson);
ArrayList<String> validationErrorDetails = new ArrayList<String>();
if (!report.isSuccess()) {
StringBuilder builder = new StringBuilder();
builder.append("Not all required fields are filled with data");
builder.append(System.getProperty("line.separator"));
for (Iterator<ProcessingMessage> i = report.iterator(); i.hasNext();) {
ProcessingMessage msg = i.next();
builder.append(msg.asJson().findValue("instance").findValue("pointer").toString());
builder.append(": ");
builder.append(msg.getMessage());
String detail = msg.asJson().findValue("instance").findValue("pointer").toString() + ": " + msg.getMessage();
detail = detail.replace("\"", "");
validationErrorDetails.add(detail);
builder.append("\n");
}
return validationErrorDetails;
}
return null;
}
}
Address.java:
package de.s2.json.test;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.github.reinert.jjschema.Attributes;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
public class Address
{
#JsonProperty("country")
private String country = "";
#JsonProperty("geoPosition")
#Attributes(required=false, description="longitude and latitude (it is initialized with 0,0)")
private GeoJsonPoint geoPosition = new GeoJsonPoint(0, 0);
}
Thank you very much for your support!
Update 1:
Answer to Hiran Chaudhuri
If the validation fails, then the schema looks like this:
{
"type": "object",
"properties": {
"country": {
"type": "string"
},
"geoPosition": {
"type": "object",
"properties": {
"coordinates": {
"type": "object"
},
"TYPE": {
"type": "string"
},
"x": {
"type": "number"
},
"y": {
"type": "number"
}
},
"description": "longitude and latitude (it is initialized with 0,0 which is inside the ocean)"
}
},
"$schema": "http://json-schema.org/draft-04/schema#"
}
If it is successful, then it looks like this:
{
"type": "object",
"properties": {
"country": {
"type": "string"
},
"geoPosition": {
"type": "object",
"properties": {
"coordinates": {
"type": "array",
"items": {
"type": "number"
}
},
"TYPE": {
"type": "string"
},
"x": {
"type": "number"
},
"y": {
"type": "number"
}
},
"description": "longitude and latitude (it is initialized with 0,0 which is inside the ocean)"
}
},
"$schema": "http://json-schema.org/draft-04/schema#"
}
As already in the error message indicated, one time the coordinates are an 'object' the other time an 'array'
Update 2
As this issue is blocking me to continue with my project, I have added an "ugly hack" to check in the schema if it contains a GeoJsonPoint. If it is included, it will patch it with the correct values.
package de.s2.json.test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.reinert.jjschema.v1.JsonSchemaV4Factory;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import com.github.fge.jsonschema.core.report.ProcessingMessage;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
public class Toolbox {
public static <T> ArrayList<String> validateJson(T inputObj) throws ProcessingException {
com.github.reinert.jjschema.v1.JsonSchemaFactory schemaFactory = new JsonSchemaV4Factory();
schemaFactory.setAutoPutDollarSchema(true);
JsonNode fstabSchema = schemaFactory.createSchema(inputObj.getClass());
ArrayList<String> validationErrorDetails = new ArrayList<String>();
// *****************************************************************************************
// /!\ this is an ugly hack /!\
// Randomly the function createSchema() returns an 'array' or 'object' type for coordinates
// of the geoJsonPoint. The correct value should be array. The following code checks if a
// geoJsonPoint is inside the schema and overwrites it with the correct value.
// TODO: fix this issue correctly
// *****************************************************************************************
try {
String jsonCoordinate = "{\"type\": \"array\",\"items\": {\"type\": \"number\"}}";
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNodeCoordinate = mapper.readTree(jsonCoordinate);
JsonNode coordJsonNode = fstabSchema.findValue("geoPosition").get("properties");
ObjectNode coordObjNode = (ObjectNode) coordJsonNode;
coordObjNode.set("coordinates", jsonNodeCoordinate);
} catch (JsonProcessingException e) {
validationErrorDetails.add("Could not patch geoPosition");
return validationErrorDetails;
} catch (IOException e) {
validationErrorDetails.add("Could not patch geoPosition");
return validationErrorDetails;
} catch (NullPointerException e) {
// this means that geoPosition could not be found
// we do nothing ...
}
// ******************
final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
final JsonSchema schema = factory.getJsonSchema(fstabSchema);
ObjectMapper objectMapper = new ObjectMapper();
JsonNode baseReceiptJson = objectMapper.convertValue(inputObj, JsonNode.class);
ProcessingReport report;
report = schema.validate(baseReceiptJson);
if (!report.isSuccess()) {
StringBuilder builder = new StringBuilder();
builder.append("Not all required fields are filled with data");
builder.append(System.getProperty("line.separator"));
for (Iterator<ProcessingMessage> i = report.iterator(); i.hasNext();) {
ProcessingMessage msg = i.next();
builder.append(msg.asJson().findValue("instance").findValue("pointer").toString());
builder.append(": ");
builder.append(msg.getMessage());
String detail = msg.asJson().findValue("instance").findValue("pointer").toString() + ": " + msg.getMessage();
detail = detail.replace("\"", "");
validationErrorDetails.add(detail);
builder.append("\n");
}
return validationErrorDetails;
}
return null;
}
}
By serializing the JSON Schema you generated we are able now to compare whether they are the same or how much they actually differ. Take into account that the method to generate a schema requires some input parameter.
I was never a friend of generating a schema based on actual data.
Why do you not strictly define the schema you want and let your code measure whether you really meet that structure? This way you can use the schema as a contract between application components since it is documented and not generated on the fly.
This is still no answer to the question why this happens randomly. But it is maybe a better practice to follow for you and others reading along.
my requirement is to read data from json file and create items in dynamoDB with the objects that are present in dynamoDB, for example consider this following file
{
"ISA": {
"isa01_name": "00",
"isa02": " ",
"isa03": "00",
"isa04": " ",
"isa05": "ZZ",
"isa06": "CLEARCUT ",
"isa07": "ZZ",
"isa08": "CMSENCOUNTERCTR",
"isa09": "120109",
"isa10": "1530",
"isa11": "U",
"isa12": "00501",
"isa13": "012412627",
"isa14": "0",
"isa15": "T",
"isa16": ":"
},
"GS": {
"gs02": "352091331",
"gs04": "20170109",
"gs06": "146823",
"gs03": "00580",
"gs05": "1530",
"gs01": "HC",
"gs08": "005010X222A1",
"gs07": "X"
},
"ST": {
"ST03_1705_Implementation Convention Reference": "005010X222A1",
"ST01_143_Transaction Set Identifier Code": "837",
"ST02_329_Transaction Set Control Number": "50138"
}
}
when i read this file it have to create ISA , GS , ST items in dynamodb database. Again if read another file having different objects , then items have to be created for them as well.
following is the code that i am having right now.
`import java.io.File;
import java.util.Iterator;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class LoadData {
public static void main(String ards[]) throws Exception {
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:8000", "us-west-2"))
.build();
DynamoDB dynamoDB = new DynamoDB(client);
Table table = dynamoDB.getTable("NewTable");
JsonParser parser = new JsonFactory().createParser(new File("C:\\Users\\Nikhil yadav\\Downloads\\healthclaims\\healthclaims\\src\\main\\resources\\output\\ValidJson.json"));
JsonNode rootNode = new ObjectMapper().readTree(parser);
Iterator<JsonNode> iter = rootNode.iterator();
ObjectNode currentNode;
while (iter.hasNext()) {
currentNode = (ObjectNode) iter.next();
try {
table.putItem(new Item().withPrimaryKey("ISA", currentNode.path("ISA").toString().replaceAll("[^:a-zA-Z0-9_-|]", " "))
.withString("GS",currentNode.path("GS").toString().replaceAll("[^:a-zA-Z0-9_-|]", " "))
.withString("ST", currentNode.path("ST").toString().replaceAll("[^:a-zA-Z0-9_-|]", " "))
);
System.out.println("PutItem succeeded: ");
}
catch (Exception e) {
System.err.println("Unable to add : ");
System.err.println(e.getMessage());
break;
}
}
parser.close();
}
}
`
it will only accept file having ISA , GS and ST objects, but i want program which accepts all types objects of json files.
i hope my question is clear. i am new in posting questions please ignore if it is not clear.
I'm a little clueless on this subject, but I'm trying to parse some Json into variables using GSON.
Here's an example of part of the Json I'm trying to parse. The goal is to get an array of objects containing the .ogg path(i.e. "minecraft/sounds/mob/stray/death2.ogg") as well as its corresponding hash variable.
{
"objects": {
"minecraft/sounds/mob/stray/death2.ogg": {
"hash": "d48940aeab2d4068bd157e6810406c882503a813",
"size": 18817
},
"minecraft/sounds/mob/husk/step4.ogg": {
"hash": "70a1c99c314a134027988106a3b61b15389d5f2f",
"size": 9398
}
}
Any help or suggestions on how to get that sort of result with GSON would be appreciated.
Xeyeler , the following is a solution that will work. A better way is to look at how GSON can convert this to an object directly. I have not tried it though
import java.util.Map;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class MainProgram {
public static void main(String[] args) {
String mineCraft = "{ \"objects\": { \"minecraft/sounds/mob/stray/death2.ogg\": { \"hash\": \"d48940aeab2d4068bd157e6810406c882503a813\", \"size\": 18817 }, \"minecraft/sounds/mob/husk/step4.ogg\": { \"hash\": \"70a1c99c314a134027988106a3b61b15389d5f2f\", \"size\": 9398 }}}";
JsonParser parser = new JsonParser();
JsonObject objects = parser.parse(mineCraft).getAsJsonObject().get("objects").getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : objects.entrySet()) {
String oggFileName = entry.getKey();
JsonElement attributes = entry.getValue();
System.out.println(
"Key is " + oggFileName + " and the hash value is " + attributes.getAsJsonObject().get("hash"));
}
}
}
I have been trying to generate Java spring code like the following.
#RequestMapping(method=RequestMethod.DELETE, value="/message/{id}")
public void reject(#PathVariable final Long id) {
return;
}
I have provided the following code in the xtend file.
members += event.toMethod(event.action.name, typeRef(void)) [
var dataType = map.get(method.action.name)
parameters += event.toParameter(method.type.parameter.name, dataType.javaType) => [
annotations += annotationRef("org.springframework.web.bind.annotation.PathVariable");
]
annotations += annotationRef("org.springframework.web.bind.annotation.RequestMapping", "method=RequestMethod.DELETE", "/message/{id}");
body = '''
return;
'''
]
and the output I am getting is
#RequestMapping({ "method=RequestMethod.DELETE", "/message/{id}" })
public void reject(#PathVariable final Long id) {
return;
}
I am confused how to provide the xtend code so that I could get the RequestMapping format as #RequestMapping(method=RequestMethod.DELETE, value="/message/{id}")
the api has no convenience for that usecase so you have to do it yourself
package org.eclipse.xtext.example.domainmodel.jvmmodel
import com.google.inject.Inject
import org.eclipse.emf.ecore.EObject
import org.eclipse.xtext.common.types.JvmAnnotationReference
import org.eclipse.xtext.common.types.JvmAnnotationType
import org.eclipse.xtext.common.types.JvmType
import org.eclipse.xtext.common.types.TypesFactory
import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.example.domainmodel.domainmodel.Entity
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmAnnotationReferenceBuilder
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.eclipse.xtext.common.types.JvmStringAnnotationValue
class DomainmodelJvmModelInferrer extends AbstractModelInferrer {
#Inject extension JvmTypesBuilder
#Inject extension IQualifiedNameProvider
def dispatch infer(Entity entity, extension IJvmDeclaredTypeAcceptor acceptor, boolean prelinkingPhase) {
accept(entity.toClass(entity.fullyQualifiedName)) [
documentation = entity.documentation
members += entity.toMethod("demo", Void.TYPE.typeRef) [
annotations +=
entity.toAnnotationRef("org.eclipse.xtext.example.domainmodel.lib.Demo", "a" -> "Hallo",
"b" -> "Welt", "c" -> "!")
body = ''''''
]
]
}
#Inject
private TypesFactory typesFactory;
#Inject
private TypeReferences references;
def toAnnotationRef(EObject context, String annotationTypeName, Pair<String, String> ... values) {
val JvmAnnotationReference result = typesFactory.createJvmAnnotationReference();
val JvmType jvmType = references.findDeclaredType(annotationTypeName, context);
if (jvmType == null) {
throw new IllegalArgumentException("The type " + annotationTypeName + " is not on the classpath.");
}
if (!(jvmType instanceof JvmAnnotationType)) {
throw new IllegalArgumentException("The given class " + annotationTypeName + " is not an annotation type.");
}
val jvmAnnotationType = jvmType as JvmAnnotationType
result.setAnnotation(jvmAnnotationType);
for (value : values) {
val JvmStringAnnotationValue annoValue = typesFactory.createJvmStringAnnotationValue
annoValue.values += value.value
annoValue.operation = jvmAnnotationType.declaredOperations.findFirst[simpleName == value.key]
result.explicitValues.add(annoValue)
}
return result
}
}
I have a inter-related Maps representing the below data .
{
"Soft Drinks": {
"Tin": [
{
"Lean Apple": [
{
"name": "1 Litre"
},
{
"name": "2 Litre"
}
]
},
{
"Clear": [
{
"name": "7 Litre"
},
{
"name": "10 Litre"
}
]
}
],
"Bottled": [
]
}
}
This is my code representing above json data in form of Java code
package test;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
public class Post {
public static void main(String args[]) throws JSONException
{
LinkedList<String> forTinItemsList = new LinkedList<String>();
LinkedList<String> forBottleItemsList = new LinkedList<String>();
JSONObject jsonobj = new JSONObject();
Map<String,LinkedList<String>> categoryitemsMap = new LinkedHashMap<String,LinkedList<String>>();
forTinItemsList.add("Lean Apple");
forTinItemsList.add("Clear");
forBottleItemsList.add("Lemon");
forBottleItemsList.add("Clear");
categoryitemsMap.put("Tin", forTinItemsList);
categoryitemsMap.put("Bottled", forBottleItemsList);
// completion of Categories.
Map<String,LinkedList<String>> subcategory = new LinkedHashMap<String,LinkedList<String>>();
LinkedList<String> forLemonItems = new LinkedList<String>();
forLemonItems.add("1 Litre");
forLemonItems.add("2 Litre");
subcategory.put("Lemon", forLemonItems);
LinkedList<String> forClearItems = new LinkedList<String>();
forClearItems.add("7 Litre");
forClearItems.add("10 Litre");
subcategory.put("Clear", forClearItems);
for (Map.Entry<String, LinkedList<String>> entry : categoryitemsMap.entrySet())
{
String key = entry.getKey();
LinkedList<String> list = entry.getValue();
for(String value : list)
{
System.out.println(key+"\t"+value);
}
//jsonobj.put(entry, arg1);
}
}
}
Could anybody please tell me how can i build the above JSON Structure ??
I was trying with different things m, but i was unsuccessful , the problem i was facing is that i am getting the Bottled Array is also filling up with the same Tin Array items .
To give you an idea of the unholy abomination things would become if you did it this way: here's the data structure that you would have to create to capture the JSON you propose.
Map<String, Map<String, List<Map<String, List<Map<String, String>>>>>> items;
So, feel free to implement this, but if it was me, I would build a data model and then map it with Jackson.
there are libraries that do this for you GSON and Jackson