Skip to content

Commit 80b6207

Browse files
author
Megan Banaski
committed
new feature guides
added new data types, query streaming (bind params/provenance), and search indexes
1 parent 747b9d3 commit 80b6207

File tree

2 files changed

+160
-2
lines changed

2 files changed

+160
-2
lines changed

guide/17-working-with-knowledge-graphs/part2_search_query_knowledge_graph.ipynb

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
" <ul class=\"toc-item\">\n",
1717
" <li><span><a href=\"#Search\" data-toc-modified-id=\"Search-1\">Search</a></span></li>\n",
1818
" <li><span><a href=\"#Query\" data-toc-modified-id=\"Query-2\">Query</a></span></li>\n",
19-
" <li><span><a href=\"#Using-Results\" data-toc-modified-id=\"Using-Results-3\">Using Results</a></span></li>\n",
19+
" <li><span><a href=\"#Query-Streaming\" data-toc-modified-id=\"Query-Streaming-3\">Query Streaming</a></span></li>\n",
20+
" <li><span><a href=\"#Using-Results\" data-toc-modified-id=\"Using-Results-4\">Using Results</a></span></li>\n",
2021
" </ul>\n",
2122
"</div>"
2223
]
@@ -112,8 +113,110 @@
112113
" }\n",
113114
" }]\n",
114115
"]\n",
115-
"```\n",
116+
"```"
117+
]
118+
},
119+
{
120+
"cell_type": "markdown",
121+
"metadata": {},
122+
"source": [
123+
"## Query Streaming\n",
124+
"\n",
125+
"Query streaming accepts a query string the same way query does, but also allows the additional parameters:\n",
126+
"- bind_param, which accepts any number of key: value pairs of parameters you would like to include in the query that are created outside of the query. This includes any primitive types as well as geometries, lists, and anonymous objects.\n",
127+
"- include_provenance, a boolean parameter used to determine whether provenance records will be returned as part of the query results.\n",
128+
"\n",
129+
"Another benefit to using query streaming is the resulting records are not limited to the server's query limits, but rather returned in chunks and presented as a generator which can be used to retrieve all results at once using list() or go through each record one at a time using next()."
130+
]
131+
},
132+
{
133+
"cell_type": "code",
134+
"execution_count": null,
135+
"metadata": {},
136+
"outputs": [],
137+
"source": [
138+
"# using bind parameters in queries\n",
139+
"\n",
140+
"# list example\n",
141+
"query_list = ['Megan', 'Emma', 'Cameron', 'Noah']\n",
142+
"results = knowledge_graph.query_streaming(\"MATCH (p:Person) WHERE p.name IN $list RETURN p\", bind_param={\"list\": query_list})\n",
116143
"\n",
144+
"# anonymous object example\n",
145+
"query_obj = {\"props\": {\"name\": \"Megan\"}, \"list\": ['Emma', 'Cameron', 'Noah']}\n",
146+
"results = knowledge_graph.query_streaming(\"MATCH (n:Person)-[:FriendsWith]-(e:Person) WHERE n.name = $object.props.name AND e.name in $object.list RETURN n, e\", bind_param={\"object\": query_obj})"
147+
]
148+
},
149+
{
150+
"cell_type": "markdown",
151+
"metadata": {},
152+
"source": [
153+
"The output of these queries are a generator, so they need to be handled slightly different from the regular query output."
154+
]
155+
},
156+
{
157+
"cell_type": "code",
158+
"execution_count": null,
159+
"metadata": {},
160+
"outputs": [],
161+
"source": [
162+
"# handling results - get all results\n",
163+
"for result in list(results):\n",
164+
" # do something with each result\n",
165+
" print(result)\n",
166+
"\n",
167+
"# handling results - get results one at a time\n",
168+
"next(results)\n",
169+
"\n",
170+
"# or loop through all results using next\n",
171+
"while True:\n",
172+
" try:\n",
173+
" # do something with each result\n",
174+
" print(next(results))\n",
175+
" except StopIteration:\n",
176+
" break"
177+
]
178+
},
179+
{
180+
"cell_type": "code",
181+
"execution_count": null,
182+
"metadata": {},
183+
"outputs": [],
184+
"source": [
185+
"# including provenance in query results\n",
186+
"results = knowledge_graph.query_streaming(\"MATCH (n:Provenance) RETURN n LIMIT 1\", include_provenance=True)\n",
187+
"list(results)"
188+
]
189+
},
190+
{
191+
"cell_type": "markdown",
192+
"metadata": {},
193+
"source": [
194+
"The result of this query would look similar to:\n",
195+
"```\n",
196+
"[\n",
197+
" [\n",
198+
" {'_objectType': 'entity',\n",
199+
" '_typeName': 'Provenance',\n",
200+
" '_id': UUID('1794b6b2-4d91-48ad-b51f-5dfb80e58c01'),\n",
201+
" '_properties': {'instanceID': UUID('3e16d8fe-7f68-45ef-805a-a54d78995411'),\n",
202+
" 'propertyName': 'name',\n",
203+
" 'sourceType': 'String',\n",
204+
" 'typeName': 'Document',\n",
205+
" 'globalid': UUID('1794b6b2-4d91-48ad-b51f-5dfb80e58c01'),\n",
206+
" 'sourceName': 'MySourceName',\n",
207+
" 'source': 'MySource',\n",
208+
" 'objectid': 2\n",
209+
" }\n",
210+
" }\n",
211+
" ]\n",
212+
"]\n",
213+
"```"
214+
]
215+
},
216+
{
217+
"cell_type": "markdown",
218+
"metadata": {},
219+
"source": [
117220
"## Using Results\n",
118221
"\n",
119222
"Query responses can get much more complex depending on what is returned from the query. openCypher allows many different types of returns including entities, relationships, properties, anonymous objects, lists, and more. Providing this response as a list of lists guarantees the response can be used once returned.\n",

guide/17-working-with-knowledge-graphs/part3_edit_knowledge_graph.ipynb

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
" <li><span><a href=\"#Deletes\" data-toc-modified-id=\"Deletes-3.2.3\">Deletes</a></span></li>\n",
3939
" </ul>\n",
4040
" </li>\n",
41+
" <li><span><a href=\"#Search-Indexes\" data-toc-modified-id=\"Search-Indexes-3.3\">Search Indexes</a></span></li>\n",
4142
" </ul>\n",
4243
" </li>\n",
4344
" </ul>\n",
@@ -298,11 +299,15 @@
298299
"\n",
299300
"The default type for a property is esriFieldTypeString, to define a different type use one of the [available field types](https://github.com/Esri/knowledge-pbf/blob/master/proto/esriPBuffer/EsriExtendedTypes/EsriExtendedTypes.proto):\n",
300301
"- esriFieldTypeSmallInteger\n",
302+
"- esriFieldTypeBigInteger\n",
301303
"- esriFieldTypeInteger\n",
302304
"- esriFieldTypeSingle\n",
303305
"- esriFieldTypeDouble\n",
304306
"- esriFieldTypeString\n",
305307
"- esriFieldTypeDate\n",
308+
"- esriFieldTypeDateOnly\n",
309+
"- esriFieldTypeTimeOnly\n",
310+
"- esriFieldTypeTimestampOffset\n",
306311
"- esriFieldTypeOID\n",
307312
"- esriFieldTypeGeometry\n",
308313
" - with this type, you also need to [define geometryType](https://github.com/Esri/knowledge-pbf/blob/master/proto/esriPBuffer/EsriTypes.proto):\n",
@@ -383,6 +388,56 @@
383388
"source": [
384389
"knowledge_graph.graph_property_delete(\"User\", \"name\")"
385390
]
391+
},
392+
{
393+
"cell_type": "markdown",
394+
"metadata": {},
395+
"source": [
396+
"### Search Indexes"
397+
]
398+
},
399+
{
400+
"cell_type": "markdown",
401+
"metadata": {},
402+
"source": [
403+
"Search indexes can be added to esriFieldTypeString properties to allow the contents of those properties to be search for when using [knowledge_graph.search()](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.search)."
404+
]
405+
},
406+
{
407+
"cell_type": "code",
408+
"execution_count": null,
409+
"metadata": {},
410+
"outputs": [],
411+
"source": [
412+
"# add search indexes to individual properties\n",
413+
"knowledge_graph.update_search_index(adds={\n",
414+
" \"User\": {\n",
415+
" \"property_names\": [\"name\"]\n",
416+
" }\n",
417+
"})\n",
418+
"\n",
419+
"# add search indexes to all text properties based on the data model\n",
420+
"datamodel = knowledge_graph.datamodel\n",
421+
"for entity_type in datamodel['entity_types']:\n",
422+
" prop_list = []\n",
423+
" for prop in datamodel['entity_types'][entity_type]['properties']:\n",
424+
" if datamodel['entity_types'][entity_type]['properties'][prop]['fieldType'] == 'esriFieldTypeString':\n",
425+
" prop_list.append(prop)\n",
426+
" knowledge_graph.update_search_index(adds={entity_type: {\"property_names\": prop_list}})\n",
427+
"for entity_type in datamodel['relationship_types']:\n",
428+
" prop_list = []\n",
429+
" for prop in datamodel['relationship_types'][entity_type]['properties']:\n",
430+
" if datamodel['relationship_types'][entity_type]['properties'][prop]['fieldType'] == 'esriFieldTypeString':\n",
431+
" prop_list.append(prop)\n",
432+
" knowledge_graph.update_search_index(adds={entity_type: {\"property_names\": prop_list}})\n",
433+
"\n",
434+
"# delete a property from the search index\n",
435+
"knowledge_graph.update_search_index(deletes={\n",
436+
" \"User\": {\n",
437+
" \"property_names\": [\"name\"]\n",
438+
" }\n",
439+
"})"
440+
]
386441
}
387442
],
388443
"metadata": {

0 commit comments

Comments
 (0)