dynamodb update list of map - java

I am trying to save List<Map<String,AttributeValue>> into dynamodb
The data looks like
"includeData" : [
{
"data" : "[VALUE]",
"work" : "[VALUE]",
"product" : "[VALUE]",
"catagory" : "[VALUE]",
"type" : "[VALUE]"
},
{
"data" : "[VALUE]",
"work" : "[VALUE]",
"product" : "[VALUE]",
"catagory" : "[VALUE]",
"type" : "[VALUE]"
}
]
In the code, I am creating the update request as
Map<String, AttributeValue> annExpressionAttributeValues = new HashMap<>();
annExpressionAttributeValues.put(V_INCLUDE_DATA, new AttributeValue().withL(Arrays.asList([LIST])));
new UpdateItemRequest().withTableName([TABLE_NAME])
.withKey(keys).withUpdateExpression("SET #includeData = :v_includeData").withExpressionAttributeNames(annExpressionAttributeNames)
.withExpressionAttributeValues(annExpressionAttributeValues).withReturnValues(ReturnValue.ALL_NEW);
I am facing at line AttributeValue().withL(Arrays.asList(annExpressionAttributeValues)));
withL is not suitable for this requirement. I cannot find any other. How can I update this data structure in dynamodb

Related

How to extract item from nested list - Rest Assured

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"
]

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 create MongoID in android code?

I am developing app with mongoDB support in android.
I want to create MongoID from java code and send it to my server.
Here is my code
I want to create this json
{
"_id" : ObjectId("59b7bcdf92e706382b00009f"),
"user_id" : "6bb82a99-bccd-4868-a799-55e7d28f969c",
"is_active" : false,
"_slugs" : [
"aaa"
],
"facility_name" : "aaa",
"industry_id" : 1,
"old_industry_id" : 1,
"established_date" : "1994-06-01",
"summary" : "this is test",
"facility_website" : "www.xxx.com",
"contact" : {
"_id" : ObjectId("4637gdff92jhsgd378364y"),
"info_type" : "PROFILE_INFO",
"name" : "xxxxxxxxxx",
"mobileNumber" : "xxxxxxxxx",
"email" : "xxxxxxx#gmail.com",
"shown_on_profile" : true
}}
But I am getting this Json from my java code.
{
"_id" : ObjectId("59b7bcdf92e706382b00009f"),
"user_id" : "6bb82a99-bccd-4868-a799-55e7d28f969c",
"is_active" : false,
"_slugs" : [
"aaa"
],
"facility_name" : "aaa",
"industry_id" : 1,
"old_industry_id" : 1,
"established_date" : "1994-06-01",
"summary" : "this is test",
"facility_website" : "www.xxx.com",
"contact" : {
"_id" : "{}",
"info_type" : "PROFILE_INFO",
"name" : "xxxxxxxxxx",
"mobileNumber" : "xxxxxxxxx",
"email" : "xxxxxxx#gmail.com",
"shown_on_profile" : true
}}
Problem is in "contact" object
Here is my java code
String _id = new JsonObject().toString(); // this is Gson.JsonObject() object
JSONObject contact = new JSONObject();
contact.put("_id", _id);
contact.put("info_type", "PROFILE_INFO");
contact.put("name", "User-1");
contact.put("mobileNumber", "xxxxxxxxxx");
contact.put("email", "xxxxx#gmail.com");
contact.put("shown_on_profile", true);
The MongoID is automatically generated by the server. What you need to do, is to send your contact without the MongoID. The server will insert the data in the database and return the MongoID of this element just created, and you can return the entire contact or just the MongoID to your Android app to use it.
As said by #fandro i have solved my issue.
Server gives me mongoDB data like this
{"_id":{"$id":"59b7bcdf92e706382b00009f"}}
I can access this data using this code,
Here is my android Code
ID = jsonData.getJSONObject("_id).getString("$id");
For generating new ID i have created empty JSONObject in android and passed to my server.
_id = new JSONObject().put("$id", "");
On my server, i check id and if it is empty then i generate new MongoID form this code,
<?php
$_id = $_POST['_id'];
if ($_id['$id'] == "")
$_id = new MongoID();
?>

$set does not change the value of the field in java driver for mongodb

My collection is something like this:
{
"_id" : ObjectId("597c4c42398593a7b464fc9c"),
"userId" : NumberLong(2),
"steps" : [
{
"_id" : ObjectId("597c4c42398593a7b464fc9a"),
"beginningDate" : "2017-07-29T13:20:10.344",
"state" : "Pending",
"messages" : [
{
"_id" : ObjectId("597c4c42398593a7b464fc9b"),
"content" : "Hi",
"isRead" : 0,
"side" : "UserToAdmin",
"creationDate" : "2017-07-29T13:20:10.344"
}
]
},
{
"_id" : ObjectId("597c4ce5398593aaa897ccb4"),
"beginningDate" : "2017-07-29T13:22:53.884",
"state" : "Open",
"messages" : []
}
],
"lastStepState" : "Pending",
"lastModified" : "2017-07-29T13:26:36.774"
}
What I'm basically trying to do is whenever I push a new step into the steps array, I update the lastStepState in the following way:
Document updateQueryDoc = new Document("userId", userId).append("lastStepState",
new Document("$eq", State.Pending.name()));
Document updateDoc = new Document("$push", new Document("steps", newStepDoc))
.append("$set", new Document("lastStepState", State.Open.name()))
.append("$set", new Document("lastModified", now));
(State is an enum with Pending and Open values)
However, the lastStepState does not gets updated. what could be the problem?
(I also should mention that there is one document in the collection, so using updateMany is not a soultion to my problem.)
Document's append uses the underlying Map's put(K key, V value) function, so when you call append("$set", new Document("lastModified", now)) it overwrites the value of the previously set $set key.
You can fix it like this:
Document updateDoc = new Document("$push", new Document("steps", newStepDoc))
.append("$set", new Document("lastStepState", State.Open.name()).append("lastModified", now));

How to construct query to update nested array document in mongo?

I am having following document in mongo,
{
"_id" : ObjectId("506e9e54a4e8f51423679428"),
"description" : "ffffffffffffffff",
"menus" : [
{
"_id" : ObjectId("506e9e5aa4e8f51423679429"),
"description" : "ffffffffffffffffffff",
"items" : [
{
"name" : "xcvxc",
"description" : "vxvxcvxc",
"text" : "vxcvxcvx",
"menuKey" : "0",
"onSelect" : "1",
"_id" : ObjectId("506e9f07a4e8f5142367942f")
} ,
{
"name" : "abcd",
"description" : "qqq",
"text" : "qqq",
"menuKey" : "0",
"onSelect" : "3",
"_id" : ObjectId("507e9f07a4e8f5142367942f")
}
]
},
{
"_id" : ObjectId("506e9e5aa4e8f51423679429"),
"description" : "rrrrr",
"items" : [ {
"name" : "xcc",
"description" : "vx",
"text" : "vxc",
"menuKey" : "0",
"onSelect" : "2",
"_id" : ObjectId("506e9f07a4e8f5142367942f")
} ]
}
]
}
Now , i want to update the following document :
{
"name" : "abcd",
"description" : "qqq",
"text" : "qqq",
"menuKey" : "0",
"onSelect" : "3",
"_id" : ObjectId("507e9f07a4e8f5142367942f")
}
I am having main documnet id: "_id" : ObjectId("506e9e54a4e8f51423679428") and menus id
"_id" : ObjectId("506e9e54a4e8f51423679428") as well as items id "_id" : ObjectId("507e9f07a4e8f5142367942f") which is to be updated.
I have tried using the following query:
db.collection.update({ "_id" : { "$oid" : "506e9e54a4e8f51423679428"} , "menus._id" : { "$oid" : "506e9e5aa4e8f51423679429"}},{ "$set" : { "menus.$.items" : { "_id" : { "$oid" : "506e9f07a4e8f5142367942f"}} , "menus.$.items.$.name" : "xcvxc66666", ...}},false,false);
but its not working...
The positional operator does not work on the number of levels you are trying to get it to work on ( https://jira.mongodb.org/browse/SERVER-831?focusedCommentId=22438&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel ) with menus.$.items.$.name and even if it did MongoDB query parser would have no idea what the other $ is from the find of the update.
You will need to pull out the items from the schema, update that seprately and then update the root document.
One good way of judging when queries should be done separately is to think that each menu sounds like a separate entity (or table in a relational database) as such you should probably work on updating those entites (or tables in a relational model) separately to the parent entity (table).
So first you would get out the main root document. Scroll across it's menus in client side and then $set that particular menu to the entire item you build on client side.
Edit
The way I imagine this work client side is (in pseudo code since my Java is a little rusty) by first getting that document in an active record fashion:
doc = db.col.find({ "_id" : { "$oid" : "506e9e54a4e8f51423679428"} ,
"menus._id" : { "$oid" : "506e9e5aa4e8f51423679429"}});
Then you would iterate through the document assigning your values:
foreach(doc.menus as menu_key => menu){
foreach(menu['items'] as key => item){
if(item._id == { "$oid" : "506e9f07a4e8f5142367942f"}){
doc.menus[menu_key][key][name] = "xcvxc66666"
}
}
}
And then simple save the doc after all changes are commited:
db.col.save(doc);
This is of course just one way of doing it and this way uses the activen record paradigm which I personally like. In this idea you would combine the find with everything else you need to modify on the document, building it up client side and then sending it all down as one single query to your DB.

Categories