How to use pagination on dynamoDB - node.js

How can you make a paginated request (limit, offset, and sort_by) using dynamoDB?
On mysql you can:
SELECT... LIMIT 10 OFFSET 1 order by created_date ASC
I'm trying this using nodejs, and in this case created_date isn't the primary key, can I query using sort key created_date?
This is my users table
{
"user_id": "asa2311",
"created_date": "2019/01/18 15:05:59",
"status": "A",
"rab_item_id": "0",
"order_id": "1241241",
"description": "testajabroo",
"id": "e3f46600-1af7-11e9-ac22-8d3a3e79a693",
"title": "test"
},
{
"user_id": "asa2311",
"status_id": "D",
"created_date": "2019/01/18 14:17:46",
"order_id": "1241241",
"rab_item_id": "0",
"description": "testajabroo",
"id": "27b5b0d0-1af1-11e9-b843-77bf0166a09f",
"title": "test"
},
{
"user_id": "asa2311",
"created_date": "2019/01/18 15:05:35",
"status": "A",
"rab_item_id": "0",
"order_id": "1241241",
"description": "testajabroo",
"id": "d5879e70-1af7-11e9-8abb-0fa165e7ac53",
"title": "test"
}

Pagination in DynamoDB is handled by setting the ExclusiveStartKey parameter to the LastEvaluatedKey returned from the previous result. There is no way to start after a specific number of items like you can with OFFSET in MySQL.

Related

How to replace existing key in jsonb?

I'm trying to update a jsonb array in Postgres by replacing the entire array. It's important to note, I'm not trying to add an array to the object, but simply replace the whole thing with new values. When I try the code below, I get this error in the console
error: cannot replace existing key
I'm using Nodejs as server-side language.
server.js
//new array with new values
var address = {
"appt": appt,
"city": city,
"street": street,
"country": country,
"timezone": timezone,
"coordinates": coordinates,
"door_number": door_number,
"state_province": state_province,
"zip_postal_code": zip_postal_code
}
//query
var text = "UPDATE users SET info = JSONB_insert(info, '{address}', '" + JSON.stringify(address) + "') WHERE id=$1 RETURNING*";
var values = [userid];
//pool...[below]
users table
id(serial | info(jsonb)
And this is the object I need update
{
"dob": "1988-12-29",
"type": "seller",
"email": "eyetrinity3#test.com",
"phone": "5553766962",
"avatar": "f",
"address": [
{
"appt": "",
"city": "Brandon",
"street": "11th Street East",
"country": "Canada",
"timezone": "Eastern Standard Time",
"coordinates": [
"-99.925011",
"49.840649"
],
"door_number": "666",
"state_province": "Manitoba",
"zip_postal_code": "R7A 7B8"
}
],
"last_name": "doe",
"first_name": "john",
"date_created": "2022-11-12T19:44:36.714Z",
}
below works in db-fiddle Postgresql v15 (did not in work in v12)
specific element
update json_update_t set info['address'][0] = '{
"appt": "12",
"city": "crater",
"street": "11th Street East",
"country": "mars",
"timezone": "Eastern Standard Time",
"coordinates": [
"-99.925011",
"49.840649"
],
"door_number": "9999",
"state_province": "marsbar",
"zip_postal_code": "abc 123"
}';
whole array
update json_update_t set info['address'] = '[{
"appt": "14",
"city": "crater",
"street": "11th Street East",
"country": "mars",
"timezone": "Eastern Standard Time",
"coordinates": [
"-99.925011",
"49.840649"
],
"door_number": "9999",
"state_province": "marsbar",
"zip_postal_code": "abc 123"
}]';
I have found the answer for this. Going through some of my older apps I coded, I stumbled upon the answer. It's not JSONB_INSERT but JSONB_SET. Notice the difference. The later will replace the entire key and not insert or add to the object.
JSONB_INSERT --> insert
UPDATE users SET info = JSONB_insert(info, '{address,-1}', '" + JSON.stringify(address) + "',true) WHERE id=$1 RETURNING*
JSONB_SET --> set and replace
UPDATE users SET info = JSONB_SET(info, '{address}', '" + JSON.stringify(address) +"') WHERE id=$1 RETURNING*

Get max of grouped documents in CosmosDb

I want to query Azure CosmosDb documents with SQL API query. These Documents shall be filtered and grouped by specific values. From these groups only the document with a specified max value shall be returned.
Example
Azure CosmosDb Documents
{
"id": "1",
"someValue": "shall be included",
"group": "foo",
"timestamp": "1668907312"
}
{
"id": "2",
"someValue": "shall be included",
"group": "foo",
"timestamp": "1668907314"
}
{
"id": "3",
"someValue": "shall be included",
"group": "bar",
"timestamp": "1668907312"
}
{
"id": "4",
"someValue": "don't include",
"group": "bar",
"timestamp": "1668907312"
}
Query
I want do get all documents
with "someValue": "shall be included"
grouped by group
from group only max of timestamp
Example response
{
"id": "2",
"someValue": "shall be included",
"group": "foo",
"timestamp": "1668907314"
},
{
"id": "3",
"someValue": "shall be included",
"group": "bar",
"timestamp": "1668907312"
}
Question
What is the best way to do this? It would be optimal if
it is possible in one query
and executable with Azure SDK with use of SqlParameter (to prevent injection)
What i've tried
My current approach consists of 2 queries and uses ARRAY_CONTAINS, which does not allow the use of SqlParameter for the document paths.
{
"id": "2",
"some-value": "shall be included",
"group": "foo",
"timestamp": "1668907314"
}
First Query
SELECT c.group AS group
MAX(c.timestamp) AS maxValue
FROM c
WHERE c.someValue = 'shall be included'
GROUP BY c.group
Second Query
SELECT * FROM c WHERE ARRAY_CONTAINS(
<RESULT-FIRST-QUERY>,
{
"group": c.group,
"maxValue": c.timestamp
},
false
)
I would utilize the MAX() function in conjunction with GROUP BY i.e
SELECT *
FROM c
WHERE c.someValue = "shall be included"
GROUP BY c.group
HAVING MAX(c.timestamp)
Haven't run that yet/need to make a collection, but seems like it should do the trick...

Is sorting rows by UUID a bad way in Cassandra?

I have a simple table and I want to sort by descending it. I added a parent_id and it's value is zero always. Is this a bad way to order by?
CREATE TABLE postcards (
id uuid,
parent_id tinyint,
body text,
PRIMARY KEY (parent_id, id)
) WITH CLUSTERING ORDER BY (id DESC)
SELECT * FROM postcards;
And query result:
[
{
"parent_id": 0,
"id": "f6b53ed0-aa30-11ec-8dc2-38f3ab100fe8",
"body": "7"
},
{
"parent_id": 0,
"id": "f507fa4b-aa30-11ec-8dc1-38f3ab100fe8",
"body": "6"
},
{
"parent_id": 0,
"id": "f31a2ced-aa30-11ec-8dc0-38f3ab100fe8",
"body": "5"
},
{
"parent_id": 0,
"id": "f1ab7e36-aa30-11ec-8dbf-38f3ab100fe8",
"body": "4"
},
{
"parent_id": 0,
"id": "f0897c34-aa30-11ec-8dbe-38f3ab100fe8",
"body": "3"
},
{
"parent_id": 0,
"id": "ef61185e-aa30-11ec-8dbd-38f3ab100fe8",
"body": "2"
},
{
"parent_id": 0,
"id": "ee1f9399-aa30-11ec-8dbc-38f3ab100fe8",
"body": "1"
}
]
If you will ever have just the one parent_id, this makes no sense because the data will only ever be owned by one node in the cluster (+ replicas).
Whether you sort the rows in ascending or descending is neither bad nor good. The more appropriate question is "What problem are you trying to solve?" because we would be able to give you a better answer if we have context on what you are trying to achieve.
If you're able to update your question with those details, I'd be happy to update my answer. Cheers!

ArangoDB offset doesn't work in join

I got next tables: users_categories, users.
users_categories objects contains "users" fields which has keys only, so I make join:
FOR c IN users_categories
FILTER c._key == '75a65608-7e9b-4e74-be19-76882209e388'
FOR u IN c.users
FOR u2 IN users FILTER u == u2._key
LIMIT 0, 100
RETURN u2
Result:
[
{
"_key": "5b1b68db-9848-4a0a-81b3-775007f16845",
"_id": "users/5b1b68db-9848-4a0a-81b3-775007f16845",
"_rev": "_VXo9gaC---",
"activated": true,
"blocked": false,
"citizenship": "RU",
"city": "Kalinigrad",
"deleted": false,
"email": "trigger.trigg#yandex.ru",
"lastActivityTime": 1501539830209,
"login": "triggerJK",
"name": "Max",
"passportId": "8736e8e4-9390-44e7-9e21-b17e18b1ebd9",
"phone": "89092132022",
"profileName": "Default profile",
"sex": 1,
"surname": "Max"
},
{
"_key": "0965a0d9-fc91-449f-90f8-9086944b1a86",
"_id": "users/0965a0d9-fc91-449f-90f8-9086944b1a86",
"_rev": "_VWjRYHe---",
"activated": true,
"blocked": false,
"citizenship": "AF",
"deleted": false,
"email": "megamozg4#mail.ru",
"lastActivityTime": 1501247531,
"login": "Megamozg4",
"passportId": "20ab7aad-d356-4437-86b2-6dfa9c4467e0",
"phone": "12312334555",
"profileName": "Default profile",
"sex": 1
}
]
If I set LIMIT 1 or LIMIT 0, 1 it returns only first record, as I want to. However, if I set LIMIT 1, N (N can be any) it returns empty array, so offset doesn't work?
What am I doing wrong?
ArangoDB used: 3.1.10
UPD:
somehow, LIMIT 1, N skips not the only first record, but first 2.
If I have more than 2 records to show, offset works strange. I created issue on github
Two bugs were reported regarding offsets:
https://github.com/arangodb/arangodb/issues/2928
https://github.com/arangodb/arangodb/issues/2879
And the fixes for LIMIT are included in the versions v3.1.27 and v3.2.1, so please update and test again.

Update inner object in arangodb

I have an object stored in arangodb which has additional inner objects, my current use case requires that I update just one of the elements.
Store Object
{
"status": "Active",
"physicalCode": "99999",
"postalCode": "999999",
"tradingCurrency": "USD",
"taxRate": "14",
"priceVatInclusive": "No",
"type": "eCommerce",
"name": "John and Sons inc",
"description": "John and Sons inc",
"createdDate": "2015-05-25T11:04:14+0200",
"modifiedDate": "2015-05-25T11:04:14+0200",
"physicalAddress": "Corner moon and space 9 station",
"postalAddress": "PO Box 44757553",
"physicalCountry": "Mars Sector 9",
"postalCountry": "Mars Sector 9",
"createdBy": "john.doe",
"modifiedBy": "john.doe",
"users": [
{
"id": "577458630580",
"username": "john.doe"
}
],
"products": [
{
"sellingPrice": "95.00",
"inStock": "10",
"name": "School Shirt Green",
"code": "SKITO2939999995",
"warehouseId": "723468998682"
},
{
"sellingPrice": "95.00",
"inStock": "5",
"name": "School Shirt Red",
"code": "SKITO245454949495",
"warehouseId": "723468998682"
},
{
"sellingPrice": "95.00",
"inStock": "10",
"discount": "5%",
"name": "School Shirt Blue",
"code": "SKITO293949495",
"warehouseId": "723468998682"
}
]
}
I want to change just one of the products stock value
{
"sellingPrice": "95.00",
"inStock": "10",
"discount": "5%",
"name": "School Shirt Blue",
"code": "SKITO293949495",
"warehouseId": "723468998682"
}
Like update store product stock less 1 where store id = x, something to this effect
FOR store IN stores
FILTER store._key == "837108415472"
FOR product IN store.products
FILTER product.code == "SKITO293949495"
UPDATE product WITH { inStock: (product.inStock - 1) } IN store.products
Apart from the above possibly it makes sense to store product as a separate document in collection store_products. I believe in NOSQL that is the best approach to reduce document size.
Found answer
here arangodb-aql-update-single-object-in-embedded-array and there
arangodb-aql-update-for-internal-field-of-object
I however believe it is best to maintain separate documents and rather use joins when retrieving. Updates easily

Resources