How to extract item from nested list - Rest Assured - java

I've got this json object
{
"type" : "employee",
"columns" :
[
{
"id" : 1,
"human" :
[
{
"name" : "ANA",
"age" : "23"
},
{
"name" : "IULIA",
"age" : "22"
}
]
},
{
"id" : 2,
"human" :
[
{
"name" : "ADI",
"age" : "21"
},
{
"name" : "GELU",
"age" : "18"
}
]
}
]
}
and I need to extract the first name from each human list.
I've tried .body("columns.human.name[0]", everyItem(containsString("A"))) but it doesn't work. Any ideas?

Using JsonPath you can get all columns and all humans.
Each of JSON Object is represented as HashMap<>. If it contains only fields it's HashMap<String, String> but if contains arrays or nested JSON Objects then it is HashMap<String, Object> where Object is either another JSON Object or array.
Given the above you can use following code to get all columns and name of first human in each column:
JsonPath path = response.jsonPath();
List<HashMap<String, Object>> columns = path.getList("columns");
for (HashMap<String, Object> singleColumn : columns) {
List<HashMap<String, Object>> humans = (List<HashMap<String, Object>>) singleColumn.get("human");
System.out.println(humans.get(0).get("name"));
}
The above code will print ANA and ADI in the console.
You can store the results in List<String> for further processing

you can get all "name" from humans with jsonPath : $.columns[*].human[*].name it will give below result :
[
"ANA",
"IULIA",
"ADI",
"GELU"
]
And if you want only first "name" then you need to use josn : $.columns[*].human[0].name this will give you below result:
[
"ANA",
"ADI"
]

Related

Fetch common elements from List<Map<String,Object>> in Java

I need to get the common elements from List<Map<String,Object>> and print that result. Below is the example where the result would be some json.
Ex:
[
{
"Id" : "123",
"common" : [
{
"group":"abc",
"department" : "xyz"
},
{
"group":"abc",
"department" : "zyx"
}
]
]
Depends what the type of Object
List<Map<String,Object>> o = ...
Object common = o.get(0).get("common");
// if object is of type Map<String, String>
Map<String,Object> data = (Map<String,Object>) common;

How to join 2nd list with first list based on a field in 1st list?

I have 2 lists, the 1st list contains a field that can be duplicated and seconds list contain the same field without duplicate with other fields. What I need is to join the two list to one based on that common field.
List 1 :
[
{
"id" : "1"
"name : "hello",
"item_name": "Name"
},
{
"id" : "1"
"name : "hi"
"item_name": "Name2"
},
{
"id" : "2"
"name : "hello"
"item_name": "Name"
}
]
Second List :
[{
"id" : "1"
"age" : "10",
"place" : "0",
"date" : "0"
},
{
"id" : "2"
"age" : "12",
"place" : "1",
"date" : "0
}]
Expected Result :
[
{
"id" : "1"
"name : "hello",
"item_name": "Name",
**"age" : "10",
"place" : "0",
"date" : "0**
},
{
"id" : "1"
"name : "hi"
"item_name": "Name2"
**"age" : "10",
"place" : "0",
"date" : "0"**
},
{
"id" : "2"
"name : "hello"
"item_name": "Name"
**"age" : "12",
"place" : "1",
"date" : "0"**
}
]
Bold areas are joined from the second list
Please help in this
I have tried :
Map<String, String> listMap = list2
.stream()
.collect(Collectors.toMap(List1Entity::getId,
List1Entity::getId));
list1.forEach(a -> {
a.setPlace(listMap.get(a.getId()));
});
But getting error at .collect(),
no instances or type variable exist so that List2Entity conforms to
List1Entity
Did you mean List2Entity in the first statement?
Map<String, String> listMap = list2
.stream()
.collect(Collectors.toMap(List2Entity::getId,
List2Entity::getPlace));
Your requirements are a bit unclear when it comes to define the joining part between the two lists.
You can start with something like this and adapt mapFunction to your needs.
String list1 = "[{\"id\":\"1\",\"name\":\"hello\",\"item_name\":\"Name\"},{\"id\":\"1\",\"name\":\"hi\",\"item_name\":\"Name2\"},{\"id\":\"2\",\"name\":\"hello\",\"item_name\":\"Name\"}]";
String list2 = "[{\"id\":\"1\",\"age\":\"10\",\"place\":\"0\",\"date\":\"0\"},{\"id\":\"2\",\"age\":\"12\",\"place\":\"1\",\"date\":\"0\"}]";
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> l1 = mapper.readValue(list1, new TypeReference<List<Map<String, Object>>>(){});
List<Map<String, Object>> l2 = mapper.readValue(list2, new TypeReference<List<Map<String, Object>>>(){});
final UnaryOperator<Map<String, Object>> mapFunction = map -> {
final String id = map.get("id").toString();
l2.stream()
.filter(map2 -> map2.get("id").toString().equals(id))
.findAny()
.ifPresent(map::putAll);
return map;
};
List<Map<String, Object>> result = l1
.stream()
.map(mapFunction)
.collect(Collectors.toList());

Mongodb Java Driver Insert Array to Collection

I have a little problem while inserting array values to existing collection in MongoDB. I have a collection as below ;
{ "_id" : "1", "username" : "", "password" : "!", "firm" : "SpringSource", "roles" : [ "admin", "client" ], "items" : [ { "_id" : "1b7cb58b-dc5b-4d27-9402-d43d3844d11d", "id" : 1, "title" : "Coffee", "price" : "12", "category" : "Coffee", "images" : "Obj1", "description" : "Coffee" } ], "latitude" : "39.877619", "longitude" : "32.682537" }
What I need is changing "images" tag's value to array value as below;
"items" : [ { "_id" : "1b7cb58b-dc5b-4d27-9402-d43d3844d11d", "id" : 1, "title" : "Coffee", "price" : "12", "category" : "Coffee", "images" : ["Obj1","Obj2"], "description" : "Coffee" } ], "latitude" : "39.877619", "longitude" : "32.682537" }
I have Items class in Java and objects of this class inserted to MongoDB as below;
Item item= new Item(id,title,price,category,image,description);
//String all=item.toString();
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(item);
Document doc = Document.parse( json.toString() );
db.getCollection("users").updateOne(new Document("username",uname1),
new Document("$push", new Document("items", doc)));
It works as expected but as I indicated above I need to store images as an array. I tried something below;
List<String> topics = new ArrayList<String>();
topics.add("Obj1");
topics.add("Obj2");
col.findOneAndUpdate(Filters.eq("_id", new. ObjectId("58b1404d002d2b1a481b8ddf")), Updates.pushEach("images", topics));
But it did not work. I have searched a lot there are many examples but I could not figure out how to do. Any recommendations?
Thanx
The simplest idea is to change Item class and instead of
String images;
change to
List<String> images;

How to use Jackson to Marshall a list of JSON objects that contain unknown number of KV paiirs

Lets say that you have a json array that looks as follows :
[
{
"id" : 1,
"first_name" : "Jane",
"last_name" : "Doe"
},
{
"id" : 2,
"first_name" : "John",
"middle_name" : "Q",
"last_name" : "Public",
"birth_year" : 1971
},
{
"id" : 3,
"anonymous_user" : true,
"crm_id" : "abc123"
},
{
"id" : 4,
"first_name" : "Albert",
"last_name" : "Einstein",
"profession" : "Scientist",
"birth_year" : 1879,
"e_equals_mc_squared" : true
}
]
The goal is to use Jackson to marshal to POJO. My thinking is that I could have a class to contain each K,V pair .. something like :
public class myDataObject {
private String key;
private T value;
...
}
And maybe a container class for that :
public class myDataContainer {
private ArrayList<myDataObject> dataList;
...
}
My question becomes what does marshaling that look like using jackson? There is no schema for the json, each json object can have an unspecified number of K,V pairs and the list of keys is also unspecified.
Does something like this work? Is this even the right approach?
ArrayList<myDataContainer> dataList = mapper.readValue(jsonFile, new TypeReference<ArrayList<myDataContainer>() {});
What your JSON really is, is a list of maps - with Strings as keys and Objects as values.
So, using Jackson, you should be able to do:
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> data = mapper.readValue(json, new TypeReference<List<Map<String, Object>>>(){});

retrieve values from nested json array in mongodb

My mongo collection has entries in the following format
{
"myobj" : {
"objList" : [
{ "location" : "Texas" },
{ "location" : "Houston"},
{ "name":"Sam" }
]
},
"category" : "cat1"
}
{
"myobj" :
{
"objList" : [
{ "location" : "Tennesy" },
{ "location" : "NY"},
{ "location" : "SF" }
]
},
"category" : "cat2"
}
I want to extract the "**category**" where location is "Houston". In case of simple JSON object I have to just pass it as query like:
BasicDBObject place = new BasicDBObject();
place.put("location", "Houston");
But in case of nested JSON I don't know how to pass it as a query and get the appropriate category. ie If I pass my location as"Houston" then it should return it's appropriate category "cat1"...i hope my question is clear now....
Ok, you have your documents:
db.coll1.insert({
"myobj" : {
"objList" : [
{ "location" : "Texas" },
{ "location" : "Houston"},
{ "name":"Sam" }
]
},
"category" : "cat1"
})
and
db.coll1.insert({
"myobj" : {
"objList" : [
{ "location" : "Tennesy" },
{ "location" : "Houston"},
{ "location" : "SF" }
]
},
"category" : "cat1"
})
Now you can find what you want using the dot operator:
db.coll1.find({"myobj.objList.location": "Texas"}).pretty() will return one object which has Texas
db.coll1.find({"myobj.objList.location": "SF"}).pretty() will return one object which has SF
db.coll1.find({"myobj.objList.location": "Houston"}).pretty() will return both objects
And now I hope you will be able to write it in Java. I have never used Java, but based on this question you can do something like this. If it will not work, just look how to use dot operator in java driver for mongo:
DBCursor cursor = coll1.find(new BasicDBObject("myobj.objList.location", "Texas"));
P.S. you told, that you wanted to retrieve category. In such a way, you will need to use a projection db.coll1.find({<the query I provided}, {category: 1, _id: 0})

Categories