Remove and add item to list in DynamoDB - amazon-dynamodb

Is there a way to, in a single DynamoDB operation, remove the last item of a list and insert a new one at the beginning of the same list?
I can only find solutions that involve two operations.

Related

kotlin firebase remove child

I'm trying to delete a specific value from a firebase realtime database, but I don't know how to do it because I don't know to save or find the key value of the child which is automatically generate.
If you see the picture I've only managed to remove all the children from the first key with
FirebaseDatabase.getInstance().reference.child("Comentarios").removeValue()
But I need to delete just by the child creadoPor
Is there any way of skkiping an unnamed child?
FirebaseDatabase.getInstance().reference.child("Comentarios").removeValue()
But I need to delete just by the child creadoPor.
Since you know the "grantparent" key of the data and the value of one of the nodes properties, you can use a query to find the nodes that match that value.
FirebaseDatabase.instance
.ref("Comentarios")
.child("-NGi7xP...")
.orderByChild("creadoPor")
.equalTo("R7lji3...")
When you get the DataSnapshot from the query, you'll need to loop over its children as shown in the documentation on listening for value events. Even when there's only one result, you'll get a list of one child node and thus will need to loop over them.

How to update value of element in an array stored as a FieldValue in Firestore

I stored an Array as a FieldValue in one of my document in Firestore. Now I want to update one of its element value. As per the documentation I can use arrayRemove or arrayUnion function to remove the element from array but I didn't see any method to update the value of element. Is there any way that I can help me to update the elements' value.
Here I stored array in "patients" field of document. This array represents list of patients. Look at 0th position of element. Here status's value is "current". I want to update this to "processed". Is there anyway that I can do so.
Also is there any way that I can query the elements of array on the basis of the value placed on status key.
As per the documentation I can use arrayRemove or arrayUnion function to remove the element from an array.
There is no way you can use one of those functions to add or remove elements from an array that contains objects. To be able to use those functions, your array should contain for example literal strings. In that way, you can add or remove one of the elements using arrayRemove() or arrayUnion() functions.
I didn't see any method to update the value of an element.
There is no update method. arrayUnion() method will add a new element in the array only if it does not exist. If you want to update an element, you have to remove it first from the array and then add the new one. This is also available in the case of strings and not in the case of objects.
Is there any way that I can help me to update the elements' value.
Yes, two ways in which you can achieve this. The first one would be to get the entire document, get the patients property as a list of hashmaps, iterate through its elements, make the desired changes and write the document back. The second one would be to transform that array into a subcollection where each patient will become a document. In this way, you can simply update add or remove a document using the corresponding functions.
Also is there any way that I can query the elements of the array on the basis of the value placed on the status key.
Using your current document structure, no. If you want to query the patients of a user based on the value of a specific property, you should definitely use the second approach. There is no way you can achieve this using your actual schema.

DynamoDB index only a specific set of values

My dynamoDB index is flooding with huge data. I would like to choose values that could be indexed and avoid indexing the rest. Is this possible?
Lets say, below are the sample items:
parent item:
{
"hashKey":"a1"
"indexHashKey":"parentType"
"indexRangeKey":"date1"
}
child item:
{
"hashKey":"a2"
"indexHashKey":"childType"
"indexRangeKey":"date11"
}
In my use case, I am always going to ask index to fetch only parentType records. The index is getting loaded with huge data because the childTypes are also getting indexed (and thats the nature). I would like to choose specific values (lets say 'parentType1', 'parentType2') to get indexed in dynamoDB. Is there any feature dynamoDB provides for this purpose?
Alternative:
If there is no such capability dynamoDB provides, then I should either
* avoid storing the child type of the item. But it would be good to have the child type stored.
or
* Maintain two different fields. One to store parent record type and another to store child record type. This looks ugly.
Any suggestions would be helpful.
To be clear, you are storing both parent and child items in a single table and want an index on the table to only contain child items? Is this a correct representation of your problem?
If you do not want all the data in a DynamoDB table to be in an index, you need to design a sparse index, which is a regular index where the attributes specified for the index hash & range keys are NOT on every item in the table. Your issue is that your 'indexHashKey' and 'indexRangeKey' attributes are on ALL your parent and child items, so they are all showing up in your index. Remember, items in a DynamoDB table can have different attributes; at a minimum, they need to contain the table's hash key and sort key (if the table has one), but they do not need to contain attributes that happen to be keys for any index attached to the table.
Consider modifying your items to only include the index hash & range key attributes on your parent items. For example:
parent item:
{
"hashKey":"a1"
"parentIndexHashKey":"parentType"
"parentIndexRangeKey":"date1"
}
Then you can do a query on that index by parent type (e.g. parentType == "parentType2") and return only the parent items in that table with that type.
If you also need to run a similar query for only child items, you can create a second sparse index that only has child items, by setting attributes for that index's hash and sort keys only on child items.
child item:
{
"hashKey":"a2"
"childIndexHashKey":"childType"
"childIndexRangeKey":"date11"
}
Alternatively, you can store parent and child items in separate DynamoDB tables so that there is no way for child items to get into the parent index and interfere with your queries.

Using timestamp as an Attribute in DynamoDB

I'm quite new to DynamoDB, but have some experience in Cassandra. I'm trying to adapt a pattern I followed in Cassandra, where each column represented a timestamped event, and wondering if it will carry over gracefully into DynamoDB or if I need to change my approach.
My goal is to query a set of documents within a date range by using the milliseconds-since-epoch timestamp as an Attribute name. I'm successfully storing the following as each report is generated with each new report being added under its own column:
{ PartitionKey:customerId,
SortKey:reportName_yyyymm,
'#millis_1#':{'report':doc_1},
'#millis_2#':{'report':doc_2},
. . .
'#millis_n#':{'report':doc_n}
}
My question is, given a millisecond-based date range, and the accompanying Partition and Sort keys, is it possible to query the set of Attributes that fall within that range or must I retrieve all columns for the matching keys and filter them at the client?
Welcome to the most powerful NoSQL database ;)
To kick off with the positive news, there is no way to query out specific attributes. You can project certain attributes in a query. But you would have to write your own logic to determine which attributes or columns should be included in the projected query. To get close to your solution you could use a map attribute inside an item with the milliseconds as a key. But there is another thing you have to be aware of when starting on this path.
There is a maximum total item size of 400KB for each item in DynamoDB, including key and attribute names.(Limits in DynamoDB Items) This means you can only store so many attributes in an item. This is especially true if you intend to put the actual report inside of the attribute. Which I would advise against, also because you will be burning up read capacity units every time you get one attribute out of the whole item. You would be better of putting this data in a separate table with the keys in the map. But truthfully in DynamoDB I would split this whole thing up, just add the milliseconds to the sort key and make every document its own item. That way you can directly query to these items and you can use the "between" where clause to select specific date-time ranges. Please let me you meant something else.

dynamodb batch write updates existing items

In this dynamodb documentation it is stated that existing items can not be updated with batch writing. However, when I try it replaces new items. How can I prevent it to update already exists one?
As stated in the documentation if you re-put an item it replaces the old one.
Update item adds/changed attributes but doesn't remove other ones.
So basically what you are doing is replacing items and not updating them.
With batch write you can't put conditions on individual items thus you can't prevent it from updating.

Resources