Increment Number Property in AWS DynamoDB - amazon-web-services

How do I increment a number in AWS Dynamodb?
The guide says when saving an item to simply resave it:
http://docs.aws.amazon.com/mobile/sdkforios/developerguide/dynamodb_om.html
However I am trying to use a counter where many users may be updating at the same time.
Other documentation has told me to use and UpdateItem operation but I cannot find a good example to do so.
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html
However, I cannot find a method to implement the expression. In the future I will be adding values to arrays and maps. Will this be the same? My code is in Obj C
Currently my code looks like:
AWSDynamoDBUpdateItemInput *updateItemInput = [AWSDynamoDBUpdateItemInput new];
updateItemInput.tableName = #"TableName";
updateItemInput.key = #{
UniqueItemKey:#"KeyValue"
};
updateItemInput.updateExpression = #"SET counter = counter + :val";
updateItemInput.expressionAttributeValues =#{
#":val":#1
};

It looks like you're missing the last bit of code that actually makes the update item request:
AWSDynamoDB *dynamoDB = [AWSDynamoDB defaultDynamoDB];
[[dynamoDB updateItem:updateItemInput]
continueWithBlock:^id(AWSTask *task) {
if (task.error) {
NSLog(#"The request failed. Error: [%#]", task.error);
}
if (task.exception) {
NSLog(#"The request failed. Exception: [%#]", task.exception);
}
if (task.result) {
//Do something with result.
}
return nil;
}];

In DynamoDB if you want to increment the value of the any propertie/field you can use the UpdateItemRequest with action option ADD. I used in android this method would update the existing value of the field. Let me share the code snippet. You can use any actions such like add,delete,put etc.
.....
AttributeValue viewcount = new AttributeValue().withS("100");
AttributeValueUpdate attributeValueUpdate = new AttributeValueUpdate().withAction(AttributeAction.ADD).withValue(viewcount);
updateItems.put(UploadVideoData.FIELD_VIEW_COUNT, attributeValueUpdate);
UpdateItemRequest updateItemRequest = new UpdateItemRequest().withTableName(UploadVideoData.TABLE_NAME)
.withKey(primaryKey).withAttributeUpdates(updateItems);
UpdateItemResult updateItemResult = amazonDynamoDBClient.updateItem(updateItemRequest);
....
You can see the above code will add 100 count into the existing value of that field.
This code is for android but the technique would remain the same.
Thank you.

Related

APEX: Assigning a Map without a Key to a List

Sorry for the newbie question. Learning Apex here. Been working on an issue for several hours and can't seem to needle it out.
I have a JSON that I need converted to a List... the JSON is retrieved via an API. The code is pretty simple, it is only a couple of lines.
The JSON looks like this:
{"id":1,"abbreviation":"ATL","city":"Atlanta","conference":"East","division":"Southeast","full_name":"Atlanta Hawks","name":"Hawks"}
And the code I am told to use to retrieve it looks like this:
Map<String, Object> resultsMap = (Map<String, Object>) JSON.deserializeUntyped(results.getBody());
Based on the JSON provided, there does not appear to be a MAP key being assigned, so I have no idea how to get it so that I may assign it to a List...
I've already tried assigning it directly to a List, but I didn't get much success there either.
I've tried this already:
List<Object> other = (List<Object>) results.get('');
I've also tried this:
List<Object> other = (List<Object>) results.keySet()[0];
I'm sure it is something simple. Any help would be appreciated.
Thanks
You cant convert the map to a list without an id. Alternatively why to convert it to List. Use the map itself. Below is a code example of how you can use it using your JSON response. For example, I want to insert this JSON response into the contact record, so I can map it using the MAP itself.:
#RestResource(urlMapping='/URIId/*')
global class OwneriCRM {
#HttpPut
global static String UpdateOwnerinfo(){
RestRequest req= RestContext.request;
RestResponse res= RestContext.response;
res.addHeader('Content-type','application/JSON');
Map<String,Object> responseresult=new Map<String,Object>();
Map<String,Object> results= (Map<String,Object>)JSON.deserializeUntyped(req.requestBody.toString());
List<contact> insertList = new List<contact>();
for (String key : results.keySet()){
System.debug(results.get(key));
contact c= new contact();
c.ContactField__C = results.get(id);
c.ContactField1__C = results.get(city);
c.ContactField2__C = results.get(conference);
c.ContactField3__C = results.get(division);
c.ContactField3__C = results.get(full_name);
c.ContactField3__C = results.get(name);
insertList.add(c);
}
if(!insertList.Isempty()){
update insertList;
}
Question can be disregarded. Not sure if there is a way to withdraw the question.
Question was based on the fact that previous APIs had been sent in the following format:
{"data": {"more stuff": "stuff"} }
And the map key was 'data' with a list. In this scenario, the whole API was a list and the keys to the map were set in place with the actual values instead.

DynamoDB Java AWS SDK - UpdateItem simplification possible?

I am new to using AWS and am writing something that will add an attribute to the provided item given some keyAttributes. I got it working, but the code I ended up writing just looks unintuitive and silly to me. (I just based it off of documentation I've been finding online.)
I was able to do a successful basic update of an item in a dynamoDB table with this code:
final AttributeValue fulfilled = new AttributeValue().withBOOL(true);
final UpdateItemRequest updateItemRequest = new UpdateItemRequest()
.withTableName(tableName)
.withKey(keyAttributes)
.withUpdateExpression("SET fulfilled = :fulfilled")
.withExpressionAttributeValues(ImmutableMap.of(":fulfilled", fulfilled));
final UpdateItemResult result = dynamoClient.updateItem(updateItemRequest);
Is there anything I can do to cut it down to just the barebones thing I'm trying to do here: just adding a new attribute "fulfilled" to an item, set to true?
An UpdateItemRequest must always contain the table name and the key attributes. (Otherwise how would DynamoDB know which item to update?)
You can simplify it, though, by getting rid of the ExpressionAttributeValues, like this:
final UpdateItemRequest updateItemRequest = new UpdateItemRequest()
.withTableName(tableName)
.withKey(keyAttributes)
.withUpdateExpression("SET fulfilled = TRUE");
final UpdateItemResult result = dynamoClient.updateItem(updateItemRequest);

Retrieve item from db using ObjectMapper

I'm totally new to coding in general, so this is really my first attempt, so don't shoot me if I ask stupid questions ;) Right now I'm having trouble even understanding the the vast world of backend.
So I'm having some problems in my service, and even deciding which way is the best to go, scanning, querying... what?
So I -think- the way to go for me is scanning... I'm having trouble to retrieve an item from the database, based on the id of that item. Retrieving all items works like a charm, and I need something similar for getting one item. I'm getting confused when searching the web, and not really even understanding the difference for example scanfilter, scanexpression? That's why I haven't even come up with a good attempt... but what I need is scan the table and retrieve the item with the matching id. I tried looking at my method for retrieving all searchCases, and implement it for retrieving one it, as it should look quite the same, but no success...
EDITED method a bit: Method I need help with:
public SearchCase getSearchCase(String id){
//this is obviously for a list, but how do I do it for ONE item?
HashMap<String, AttributeValue> sc = new HashMap<String, AttributeValue>();
sc.put("scId", new AttributeValue().withS(id));
ScanRequest scanRequest = new ScanRequest()
.withTableName(searchCaseTableName)
.withFilterExpression("id = scId");
ScanResult scanResult = client.scan(scanRequest);
?????
return searchCase;
}
As a reference here is the method for retrieving all items, that does work:
public List<SearchCase> getSearchCases() {
final List<SearchCase> cases = new ArrayList<SearchCase>();
ScanRequest scanRequest = new ScanRequest()
.withTableName(searchCaseTableName);
ScanResult result = client.scan(scanRequest);
try {
for (Map<String, AttributeValue> item : result.getItems()) {
SearchCase searchCase = mapper.readValue(item.get("payload").getS(), SearchCase.class);
cases.add(searchCase);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return cases;
}
It has been forever, but thought I'd post the correct answer I fought with for a long time back in June. So this was the solution that worked for me for retrieving a single item:
public SearchCase getSearchCase(String id) throws Exception {
Table t = db.getTable(searchCaseTableName);
GetItemSpec gis = new GetItemSpec()
.withPrimaryKey("id", id);
Item item = t.getItem(gis);
SearchCase searchCase = mapper.readValue(StringEscapeUtils.unescapeJson(item.getJSON("payload").substring(1)), SearchCase.class);
return searchCase;
}
This method actually took a whole another approach then the way I originally thought I would solve this. So no Scanrequest, but using GetItemSpec and Item instead. This thus caused some funky backslashes in the JSON, so my frontend wouldn't accept before I ran it through StringEscapeUtils.unescapeJson, otherwise worked like a charm.
I'm having trouble to retrieve an item from the database, based on the id of that item
If you want to retrieve an item from DynamoDB based on some unique ID, then use load, which "Loads an object with the hash key given".

Meteor subscriptions using deps

I'm trying to implement a searching feature in a Meteor application that re-subscribes/publishes a collection on every search, so there is only the exact Collection necessary in the client. I'm creating a reactive variable searchString, then changing it to the text in the search box on every search, then splitting the string into tags:
// Client
var searchString = "";
var searchStringDep = new Deps.Dependency;
var getSearchString = function(){
searchStringDep.depend();
return searchString;
}
var handle = Deps.autorun(function(){
var tags = getSearchString().split(" ");
tags = _.map(tags, function(tag){
return tag.replace(/[^\w]/g, "");
}).filter(function(t){
return t.toLowerCase();
});
Meteor.subscribe('results', tags);
});
Template.library.events({
'submit form': function(ev){
ev.preventDefault();
searchString = ev.target.search.value;
searchStringDep.changed();
}
})
Then, publishing a new Collection on the server, based on the tags:
// Server
Meteor.publish('results', function(tags){
regTags = _.map(tags, function(tag) { return new RegExp(tag)});
return Samples.find({tags: {$in: regTags}})
});
So I'm trying to match on regexes, but am having a weird issue where the subscription only changes when I add another tag, but changing existing tags fails.
So if the first searchString was tag1 and the second tag1 tag2, it works fine.
But if the first is tag1 and the second is tag2, the Collection doesn't update.
Any help is appreciated...I'm a beginner to Meteor, so if there is a better way to do what I'm trying to do, all suggestions are welcome. Thanks so much
'change #search': function(){
Meteor.subscribe('sampleResults', $('#search').val()); // or if you want on submit it's the same idea
}
and publish like
Meteor.publish('sampleResults, function(text){
return Samples.find({tags: {$regex: text}});
}
A few things:
1) Meteor has a very nice way of setting up reactive variables with the ReactiveVar component. I would suggest using that rather than creating another dependency for a variable.
2) The name that you are subscribing to: results is different than what is published on the server sampleResults and that can cause issues.
3) If you are on Meteor >= 0.9.1 you should be using Tracker and not Deps. You can use Deps if you want, but the new updated API is Tracker and is probably more stable. See the changelog for more details on that.
4) You don't have to set your Deps.autorun function equal to a variable. So you can have it as:
Tracker.autorun(function() {
// Code here
});

Accessing Item Fields via Sitecore Web Service

I am creating items on the fly via Sitecore Web Service. So far I can create the items from this function:
AddFromTemplate
And I also tried this link: http://blog.hansmelis.be/2012/05/29/sitecore-web-service-pitfalls/
But I am finding it hard to access the fields. So far here is my code:
public void CreateItemInSitecore(string getDayGuid, Oracle.DataAccess.Client.OracleDataReader reader)
{
if (getDayGuid != null)
{
var sitecoreService = new EverBankCMS.VisualSitecoreService();
var addItem = sitecoreService.AddFromTemplate(getDayGuid, templateIdRTT, "Testing", database, myCred);
var getChildren = sitecoreService.GetChildren(getDayGuid, database, myCred);
for (int i = 0; i < getChildren.ChildNodes.Count; i++)
{
if (getChildren.ChildNodes[i].InnerText.ToString() == "Testing")
{
var getItem = sitecoreService.GetItemFields(getChildren.ChildNodes[i].Attributes[0].Value, "en", "1", true, database, myCred);
string p = getChildren.ChildNodes[i].Attributes[0].Value;
}
}
}
}
So as you can see I am creating an Item and I want to access the Fields for that item.
I thought that GetItemFields will give me some value, but finding it hard to get it. Any clue?
My advice would be to not use the VSS (Visual Sitecore Service), but write your own service specifically for the thing you want it to do.
This way is usually more efficient because you can do exactly the thing you want, directly inside the service, instead of making a lot of calls to the VSS and handle your logic on the clientside.
For me, this has always been a better solution than using the VSS.
I am assuming you are looking to find out what the fields looks like and what the field IDs are.
You can call GetXml with the ID, it returns the item and all the versions and fields set in it, it won't show fields you haven't set.