Skip to content

Commit

Permalink
key/value part
Browse files Browse the repository at this point in the history
  • Loading branch information
hemidactylus committed May 11, 2022
1 parent a73d952 commit fb85e08
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 83 deletions.
172 changes: 89 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ It doesn't matter if you join our workshop live or you prefer to do at your own

To get the verified badge, you have to complete the following steps:

1. Complete the practice steps of this workshop as explained below. Steps 1-4 (Astra account + tabular/document/key-value databases) are mandatory, step 5 (graph database) is optional. Take a screenshot of the last completed step for steps 2, 3 and 4. _NOTE: When taking screenshots ensure NOT to copy your Astra DB secrets!_
1. Complete the practice steps of this workshop as explained below. Steps 1-4 (Astra account + tabular/document/key-value databases) are mandatory, step 5 (graph database) is optional. Take a screenshot of completion of the last step for sections 2, 3 and 4 (either a CQL command output or a response in the Swagger UI). _NOTE: When taking screenshots ensure NOT to copy your Astra DB secrets!_
<!-- x. Complete [try-it-out scenario](https://www.datastax.com/try-it-out) and make a screenshot of the "scenario completed" screen -->
2. Submit the practice [here](https://dtsx.io/nosql-ws-hw), answering test questions and attaching the screenshots.

Expand All @@ -37,7 +37,9 @@ To get the verified badge, you have to complete the following steps:
**`ASTRADB`** is the simplest way to run Cassandra with zero operations at all - just push the button and get your cluster. No credit card required,
a monthly free credit to use, covering about 20M reads/writes and 80GB storage (sufficient to run small production workloads), all for FREE.

**Step 1a:** Click the button below to login or register with Datastax. You can use your `Github`, `Google` accounts or register with an `email`.
### ✅ 1a. Register a free account on Astra

Click the button below to login or register on DataStax Astra DB. You can use your `Github`, `Google` accounts or register with an `email`.

<a href="https://astra.dev/2-9"><img src="https://github.com/datastaxdevs/workshop-graphql-netflix/raw/master/img/create_astra_db.png?raw=true" /></a>

Expand All @@ -47,7 +49,7 @@ a monthly free credit to use, covering about 20M reads/writes and 80GB storage (
|---|---|
|**database name**| `workshops` |
|**keyspace**| `nosql1` |
|**Cloud Provider**| *Use the one you like, click a cloud provider logo, pick an Area in the list and finally pick a region.* |
|**Cloud Provider**| Stick to GCP and then pick an "unlocked" region to start immediately |

More info on account creation [here](https://awesome-astra.github.io/docs/pages/astra/create-account/).

Expand Down Expand Up @@ -182,6 +184,11 @@ VALUES(
SELECT * FROM accounts_by_user;
```

> Such a full-table query is strongly discouraged in most distributed databases
> as it involves contacting many nodes to assemble the whole result dataset:
> here we are using it for learning purposes, not in production and on a table
> with very few rows!
_👁️ Expected output_

```
Expand Down Expand Up @@ -395,7 +402,7 @@ Locate the "documents" section in the Swagger UI. You are now ready to fire requ

![image](images/05.png?raw=true)

### ✅ 3c Create a new empty collection
### ✅ 3c. Create a new empty collection

![Swagger 3c](images/swagger/swagger_3c.png)

Expand All @@ -420,7 +427,7 @@ You will get an `HTTP 201 - Created` return code.
<details><summary>Click to show a screenshot</summary>

![image](images/images/swagger_responses_annotated.png?raw=true)
![image](images/swagger_responses_annotated.png?raw=true)

</details>

Expand Down Expand Up @@ -487,7 +494,7 @@ Repeat with the following body, which has _a different structure_:

As before, the document will automatically be given an internal unique `documentId`.

### ✅ 3e Find all documents in a collection
### ✅ 3e. Find all documents in a collection

![Swagger 3e](images/swagger/swagger_3e.png)

Expand Down Expand Up @@ -539,7 +546,7 @@ _👁️ Expected output (take note of the `documentId`s of your output for late
}
```

### ✅ 3f Retrieve a document by ID its id
### ✅ 3f. Retrieve a document by ID its id

![Swagger 3f](images/swagger/swagger_3f.png)

Expand Down Expand Up @@ -571,7 +578,7 @@ _👁️ Expected output_
}
```

### ✅ 3g Search document with a "where" clause
### ✅ 3g. Search document with a "where" clause

![Swagger 3g](images/swagger/swagger_3g.png)

Expand All @@ -584,6 +591,7 @@ _👁️ Expected output_
- Click `Execute` button

*👁️ Expected output*

```json
{
"data": {
Expand Down Expand Up @@ -612,117 +620,115 @@ _👁️ Expected output_

## 4. Key/Value Databases

> **Key/Value databases** are some of the simplest and yet powerful as all of the data within consists of an indexed key and a value. Key-value databases use a hashing mechanism such that given a key, the database can quickly retrieve an associated value. Hashing mechanisms provide constant time access, which means they maintain high performance even at large scale. The keys can be any type of object, but are typically a string. The values are generally opaque blobs (i.e., a sequence of bytes that the database does not interpret). Examples include: Redis, Amazon DynamoDB, Riak, and Oracle NoSQL database. Some tabular NoSQL databases, like Cassandra, can also service key/value needs.
> **Key/Value databases** are some of the simplest and yet powerful as all of the data within consists of an indexed key and a value. Key-value databases use a hashing mechanism, so that that given a key, the database can quickly retrieve the associated value. Hashing mechanisms provide constant time access, which means they maintain high performance even at large scale. The keys can be any type of object, but are typically a string. The values are generally opaque blobs (i.e. a sequence of bytes that the database does not interpret). Examples include: Redis, Amazon DynamoDB, Riak, and Oracle NoSQL database. Some tabular NoSQL databases, like Cassandra, can also service key/value needs.
**✅ 4b. Create a table with GraphQL**
### ✅ 4a. Create a table for Key/Value

Navigate to the GraphQL playground, by clicking `Connect`, then `GraphQL API`, and finally you should see the URL under `Launching GraphQL Playground`. Ctrl-click or right-click the link to launch into a new tab.
Go to the CQL Console again and issue the following commands
to create a new, simple table with just two columns:

![Graph connect](images/graph_connect.png)
```sql
USE nosql1;

Then you need to enter in your Astra DB token to authenticate and talk to the database. Notice the "server cannot be reached" message. This is simply telling you it cannot make the connection because you are not authenticated. Click on `HTTP Headers` at the bottom and paste in your token.
CREATE TABLE users_kv (
key TEXT PRIMARY KEY,
value TEXT
);
```

![Screen Shot 2021-05-20 at 8 49 48 AM](https://user-images.githubusercontent.com/23346205/118981634-88de8380-b948-11eb-9ece-5f75f153020e.png)
### ✅ 4b. Populate the table

Paste in your token.
Insert into the table all the following entries.
Note that all inserted values, regardless of their "true" data type,
have been coerced into strings according to the table schema.
Also note how the keys are structured and how some entries reference other,
effectively creating a set of interconnected pieces of information on the users:

![Screen Shot 2021-05-20 at 8 53 07 AM](https://user-images.githubusercontent.com/23346205/118982115-18843200-b949-11eb-840c-acce0a0c562a.png)
```sql
INSERT INTO users_kv (key, value) VALUES ('user:1cafb6a4-396c-4da1-8180-83531b6a41e3:name', 'Alice');
INSERT INTO users_kv (key, value) VALUES ('user:1cafb6a4-396c-4da1-8180-83531b6a41e3:email', '[email protected]');
INSERT INTO users_kv (key, value) VALUES ('user:1cafb6a4-396c-4da1-8180-83531b6a41e3:accounts', '{83428a85-5c8f-4398-8019-918d6e1d3a93, 811b56c3-cead-40d9-9a3d-e230dcd64f2f}');

Now you are ready to go.
INSERT INTO users_kv (key, value) VALUES ('user:0d2b2319-9c0b-4ecb-8953-98687f6a99ce:name', 'Bob');
INSERT INTO users_kv (key, value) VALUES ('user:0d2b2319-9c0b-4ecb-8953-98687f6a99ce:email', '[email protected]');
INSERT INTO users_kv (key, value) VALUES ('user:0d2b2319-9c0b-4ecb-8953-98687f6a99ce:accounts', '{81def5e2-84f4-4885-a920-1c14d2be3c20}');

Use this query. Since we are creating a table we want to use the `graphql-schema` tab
INSERT INTO users_kv (key, value) VALUES ('account:83428a85-5c8f-4398-8019-918d6e1d3a93:type', 'Checking');
INSERT INTO users_kv (key, value) VALUES ('account:83428a85-5c8f-4398-8019-918d6e1d3a93:balance', '2500');

```
mutation {
kv: createTable(
keyspaceName:"nosql1",
tableName:"key_value",
partitionKeys: [ # The keys required to access your data
{ name: "key", type: {basic: TEXT} }
]
values: [ # The values associated with the keys
{ name: "value", type: {basic: TEXT} }
]
)
}
INSERT INTO users_kv (key, value) VALUES ('account:811b56c3-cead-40d9-9a3d-e230dcd64f2f:type', 'Savings');
INSERT INTO users_kv (key, value) VALUES ('account:811b56c3-cead-40d9-9a3d-e230dcd64f2f:balance', '1500');

INSERT INTO users_kv (key, value) VALUES ('account:81def5e2-84f4-4885-a920-1c14d2be3c20:type', 'Checking');
INSERT INTO users_kv (key, value) VALUES ('account:81def5e2-84f4-4885-a920-1c14d2be3c20:balance', '1000');
```

![Screen Shot 2021-05-20 at 8 58 13 AM](https://user-images.githubusercontent.com/23346205/118982905-df988d00-b949-11eb-8584-9407c9efa80e.png)
### ✅ 4c. Update a value

You can check in the CQL Console as well;
You can imagine an application "navigating the keys" (e.g, from an user to an account) for instance
when it must update a balance. The actual update would look like:

```sql
use nosql1;

describe table key_value;
INSERT INTO users_kv (key, value) VALUES ('account:81def5e2-84f4-4885-a920-1c14d2be3c20:balance', '9000');
```

*Expected output*

![image](images/cqlconsole1.png?raw=true)
Let's check:

**✅ 4c. Populate the table**

Any of the created APIs can be used to interact with the GraphQL data, to write or read data. Since we are working with data now and not creating schema you will need to **swtich to the `graphql` tab**. Also, make sure you **fill in your Astra DB token again**.
```sql
SELECT * FROM users_kv WHERE key = 'account:81def5e2-84f4-4885-a920-1c14d2be3c20:balance';
```

- *Fill the header token again*
*👁️ Expected output*

```json
{
"x-cassandra-token":"AstraCS:KDfdKeNREyWQvDpDrBqwBsUB:ec80667c...."
}
```
key | value
------------------------------------------------------+-------
account:81def5e2-84f4-4885-a920-1c14d2be3c20:balance | 9000
![Screen Shot 2021-05-20 at 9 04 47 AM](https://user-images.githubusercontent.com/23346205/118983681-af9db980-b94a-11eb-82b7-e0c852701265.png)
(1 rows)
```

Now, let’s navigate to your new keyspace `nosql1` inside the playground. **Change tab to `graphql`** and pick url `/graphql/nosql1`. Your URL should end with something like `/api/graphql/nosql1`. If you have trouble ensuring this, switch back to the `graphql-schema` tab to grab the URL and applying some surgery on it to use the end point that includes `graphql` aand the keyspace `nosql1` so that it ends with `/api/graphql/nosql1` as explained earlier.
#### Alternative update syntax

![Screen Shot 2021-05-20 at 9 13 26 AM](https://user-images.githubusercontent.com/23346205/118985049-1d96b080-b94c-11eb-87c4-0340e941d37c.png)
The same result is obtained with

```sql
UPDATE users_kv SET value = '-500' WHERE key = 'account:81def5e2-84f4-4885-a920-1c14d2be3c20:balance';
```

Then paste in the following query and click "play".
![Screen Shot 2021-05-20 at 9 17 35 AM](https://user-images.githubusercontent.com/23346205/118985407-6c444a80-b94c-11eb-9b7d-d83e35e40bf1.png)
indeed, in most key-value data stores, inserting and updating are one and the same operation
since the main goal is usually the highest performance (hence, row-existence checks are skipped altogether).

- *Execute this query*
Thus, writing entries with the key of a pre-existing entry will simply overwrite the less recent values,
enabling a very efficient and simple deduplication strategy.

```
mutation insert2KV {
key1: insertkey_value(value: {key:"key1", value:"bbbb"}) {
value {
key,value
}
}
key2: insertkey_value(value: {key:"key2", value:"bbbb"}) {
value {
key,value
}
}
}
```

- Check with CQL Console
Check once more what's in the table:

```sql
select * from key_value;
SELECT * FROM users_kv ;
```

*Expected output:*

![image](images/graphql2.png?raw=true)
*👁️ Expected output*

- *Execute this query*

```
mutation insert2KV {
key1: insertkey_value(value: {key:"key1", value:"cccc"}) {
value {
key,value
}
}
}
```
key | value
------------------------------------------------------+------------------------------------------------------------------------------
account:81def5e2-84f4-4885-a920-1c14d2be3c20:balance | -500
user:0d2b2319-9c0b-4ecb-8953-98687f6a99ce:accounts | {81def5e2-84f4-4885-a920-1c14d2be3c20}
account:811b56c3-cead-40d9-9a3d-e230dcd64f2f:balance | 1500
user:1cafb6a4-396c-4da1-8180-83531b6a41e3:accounts | {83428a85-5c8f-4398-8019-918d6e1d3a93, 811b56c3-cead-40d9-9a3d-e230dcd64f2f}
user:1cafb6a4-396c-4da1-8180-83531b6a41e3:email | [email protected]
user:1cafb6a4-396c-4da1-8180-83531b6a41e3:name | Alice
user:0d2b2319-9c0b-4ecb-8953-98687f6a99ce:name | Bob
user:0d2b2319-9c0b-4ecb-8953-98687f6a99ce:email | [email protected]
account:83428a85-5c8f-4398-8019-918d6e1d3a93:type | Checking
account:811b56c3-cead-40d9-9a3d-e230dcd64f2f:type | Savings
account:81def5e2-84f4-4885-a920-1c14d2be3c20:type | Checking
account:83428a85-5c8f-4398-8019-918d6e1d3a93:balance | 2500
- Check with CQL Console the values should have been updated. Indeed with Cassandra there are no integrity constraints, so you can de-duplicate values easily.
(12 rows)
```

[🏠 Back to Table of Contents](#table-of-content)

Expand Down
Binary file removed images/graph_connect.png
Binary file not shown.

0 comments on commit fb85e08

Please sign in to comment.