|
20 | 20 | "For these notebooks, we will be leveraging a dataset from the book [Graph Databases in Action](https://www.manning.com/books/graph-databases-in-action?a_aid=bechberger) from Manning Publications. \n",
|
21 | 21 | "\n",
|
22 | 22 | "\n",
|
23 |
| - "**Note** These notebooks do not cover data modeling or building a data loading pipeline. If you would like a more detailed description about how this dataset is constructed and the design of the data model came from then please read the book.\n", |
| 23 | + "**Note** These notebooks do not cover data modeling or building a data loading pipeline. If you would like a more detailed description about how this dataset is constructed and where the design of the data model came from then please read the book.\n", |
24 | 24 | "\n",
|
25 | 25 | "To get started, the first step is to load data into the cluster. Assuming the cluster is empty, this can be accomplished by running the cell below which will load our Dining By Friends data."
|
26 | 26 | ]
|
|
34 | 34 | "\n",
|
35 | 35 | "Throughout all the **Learning Gremlin on Neptune** notebooks, you will notice that each code block starts with either a `%` or `%%` command. These are called *workbench magic* commands, and are essentially shortcuts to specific Neptune APIs. For example:\n",
|
36 | 36 | "\n",
|
37 |
| - "* `%%gremlin` - issues a Gremlin query to the Neptune endpoint usng WebSockets\n", |
| 37 | + "* `%%gremlin` - issues a Gremlin query to the Neptune endpoint using WebSockets\n", |
38 | 38 | "* `%seed` - provides a convenient way to add sample data to your Neptune endpoint\n",
|
39 | 39 | "* `%load` - generates a form that you can use to submit a bulk load request to Neptune\n",
|
40 | 40 | "\n",
|
|
99 | 99 | " \"restaurant\": {\n",
|
100 | 100 | " \"color\": \"#ffe6cc\"\n",
|
101 | 101 | " },\n",
|
102 |
| - " \"cusine\": {\n", |
| 102 | + " \"cuisine\": {\n", |
103 | 103 | " \"color\": \"#fff2cc\"\n",
|
104 | 104 | " }\n",
|
105 | 105 | " }\n",
|
|
233 | 233 | "\n",
|
234 | 234 | "### Finding Nodes\n",
|
235 | 235 | "\n",
|
236 |
| - "The simplest traversal you can do in Gremlin is to search for nodes. In Gremlin traversals, nodes are represented by `V()`. In our example, *review*, *restaurant*, *cuisine*, *person*, *state* and *city* as represented as nodes.\n", |
| 236 | + "The simplest traversal you can do in Gremlin is to search for nodes. In Gremlin traversals, nodes are represented by `V()`. In our example, *review*, *restaurant*, *cuisine*, *person*, *state* and *city* are represented as nodes.\n", |
237 | 237 | "\n",
|
238 | 238 | "Execute the query below to search for all nodes and return them, but limit the number returned to 10."
|
239 | 239 | ]
|
|
320 | 320 | "id": "a3093ad2",
|
321 | 321 | "metadata": {},
|
322 | 322 | "source": [
|
323 |
| - "We can also do the same using the combination of `bothE()` and `otherV()`, instead of explicitly stating whether to travese outgoing or incoming edges." |
| 323 | + "We can also do the same using the combination of `bothE()` and `otherV()`, instead of explicitly stating whether to traverse outgoing or incoming edges." |
324 | 324 | ]
|
325 | 325 | },
|
326 | 326 | {
|
|
484 | 484 | "metadata": {},
|
485 | 485 | "source": [
|
486 | 486 | "### Filtering Edge by Label\n",
|
487 |
| - "Another common item you to filter on is the type or label associated with an edge. As with nodes, you can use the `hasLabel()` step associated with an edge." |
| 487 | + "Another common item to filter on is the type or label associated with an edge. As with nodes, you can use the `hasLabel()` step associated with an edge." |
488 | 488 | ]
|
489 | 489 | },
|
490 | 490 | {
|
|
523 | 523 | "%%gremlin -d $node_labels\n",
|
524 | 524 | "g.V()\n",
|
525 | 525 | ".hasLabel('person')\n",
|
526 |
| - ".where(out().hasLabel('person').count().is(gte(2))) // <-- filter only people who have at 2 or more friend connections\n", |
| 526 | + ".where(out().hasLabel('person').count().is(gte(2))) // <-- filter only people who have 2 or more friend connections\n", |
527 | 527 | ".outE()\n",
|
528 | 528 | " .hasLabel('friends')\n",
|
529 | 529 | ".inV()\n",
|
|
537 | 537 | "id": "c5abc463",
|
538 | 538 | "metadata": {},
|
539 | 539 | "source": [
|
540 |
| - "What if we wanted to get a list of all the restaurants in order to find out which cuisine's they serve? After all, all this learning has made me hungry!" |
| 540 | + "What if we wanted to get a list of all the restaurants in order to find out which cuisines they serve? After all, all this learning has made me hungry!" |
541 | 541 | ]
|
542 | 542 | },
|
543 | 543 | {
|
|
597 | 597 | "id": "8b998cd1",
|
598 | 598 | "metadata": {},
|
599 | 599 | "source": [
|
600 |
| - "Because there are no properties associated to any of our edges, running the following query won't return any records. However, you can use it to see how the same concept of filtering nodes based on properties can be applied to edge.s" |
| 600 | + "Because there are no properties associated to any of our edges, running the following query won't return any records. However, you can use it to see how the same concept of filtering nodes based on properties can be applied to edges." |
601 | 601 | ]
|
602 | 602 | },
|
603 | 603 | {
|
|
768 | 768 | "id": "0452038d",
|
769 | 769 | "metadata": {},
|
770 | 770 | "source": [
|
771 |
| - "**Note** When using `by()` after a `select()` you must specify the same number of `by()` statements as there are variables in the `select()`. Failing to doing so, will cause Gremlin to re-use whichever by() statements have been specified, starting with the first one. Now, this may not always be a problem, as we can see in the next example:" |
| 771 | + "**Note** When using `by()` after a `select()` you must specify the same number of `by()` statements as there are variables in the `select()`. Failing to do so, will cause Gremlin to re-use whichever by() statements have been specified, starting with the first one. Now, this may not always be a problem, as we can see in the next example:" |
772 | 772 | ]
|
773 | 773 | },
|
774 | 774 | {
|
|
823 | 823 | "id": "943bdceb",
|
824 | 824 | "metadata": {},
|
825 | 825 | "source": [
|
826 |
| - "Notice in the above query how we've combined `project()` and `select()` to provide us with the same results. This is because to we've needed to alias specific portions of the incoming traversal, e.g. the node representing *Dave*, and the nodes representing Dave's *friends*.\n", |
| 826 | + "Notice in the above query how we've combined `project()` and `select()` to provide us with the same results. This is because we've needed to alias specific portions of the incoming traversal, e.g. the node representing *Dave*, and the nodes representing Dave's *friends*.\n", |
827 | 827 | "\n",
|
828 | 828 | "If we were to run the following query, you'll notice something very odd happen with the results."
|
829 | 829 | ]
|
|
912 | 912 | "\n",
|
913 | 913 | "In addition to returning simple key-value pairs, we can construct more complex responses. This is a common requirement, especially when returning aggregations or when returning attributes from different variables in the matched patterns.\n",
|
914 | 914 | "\n",
|
915 |
| - "These new projections are created by using the `by()` step modulator (which is discussed more in the Loops-Repeats notebook). As we're previous seen, for each traversal step, we write a `by()` step to apply to it. The example below shows how we can return a custom string with the statement \"*person* is friends with *person*\"." |
| 915 | + "These new projections are created by using the `by()` step modulator (which is discussed more in the Loops-Repeats notebook). As we've previously seen, for each traversal step, we write a `by()` step to apply to it. The example below shows how we can return a custom string with the statement \"*person* is friends with *person*\"." |
916 | 916 | ]
|
917 | 917 | },
|
918 | 918 | {
|
|
0 commit comments