From e96d103faa5dbb1480451069b7c8ae8d79343a37 Mon Sep 17 00:00:00 2001 From: Megan Banaski Date: Mon, 6 Jan 2025 06:38:07 -0800 Subject: [PATCH 1/3] draft 1 --- .../part4_using_graphclient.ipynb | 480 ++++++++++++++++++ 1 file changed, 480 insertions(+) create mode 100644 guide/17-working-with-knowledge-graphs/part4_using_graphclient.ipynb diff --git a/guide/17-working-with-knowledge-graphs/part4_using_graphclient.ipynb b/guide/17-working-with-knowledge-graphs/part4_using_graphclient.ipynb new file mode 100644 index 0000000000..ac30c7e45f --- /dev/null +++ b/guide/17-working-with-knowledge-graphs/part4_using_graphclient.ipynb @@ -0,0 +1,480 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "266912f3", + "metadata": {}, + "source": [ + "# Using GraphClient" + ] + }, + { + "cell_type": "markdown", + "id": "aa15c594", + "metadata": {}, + "source": [ + "

Table of Contents

\n", + "
\n", + " \n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "7f686a14", + "metadata": {}, + "source": [ + "## Introduction\n", + "\n", + "`GraphClient` provides classes for common things like `EntityType`, `RelationshipType`, `Entity`, `Relationship`, `GraphProperty` and more. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e7479baa", + "metadata": {}, + "outputs": [], + "source": [ + "from arcgis.gis import GIS\n", + "from arcgis.geometry import Point\n", + "from arcgis.graph import GraphClient, EntityType, RelationshipType, Entity, Relationship, GraphProperty, EntityDelete, NamedObjectTypeMask, GraphPropertyMask, SearchIndexProperties\n", + "\n", + "gis = GIS(\"home\")\n", + "new_service = gis.content.create_service(\n", + " name=\"MyKnowledgeGraph\",\n", + " capabilities=\"Query,Editing,Create,Update,Delete\",\n", + " service_type=\"KnowledgeGraph\"\n", + ")\n", + "graph = GraphClient(new_service.url, gis=gis)" + ] + }, + { + "cell_type": "markdown", + "id": "624705dc", + "metadata": {}, + "source": [ + "## Query\n", + "\n", + "`query` in `GraphClient` will execute a `query_streaming` and provides extra query options such as using `bind_param` to define bind parameters to be used in the query and `include_provenance` which will query for provenance records if set to `True`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fe50ad2e", + "metadata": {}, + "outputs": [], + "source": [ + "result = graph.query(\"MATCH (n) RETURN n LIMIT 5\")\n", + "list(result)" + ] + }, + { + "cell_type": "markdown", + "id": "6e7f0335", + "metadata": {}, + "source": [ + "## Search\n", + "\n", + "`search` searches the graph for the given string on any properties of both entities or relationships by default. To search for properties on only entities or only relationships you can use the `category` parameter on `search` and set the value to either `entities`, `relationships`, or `both` (default)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1fba59eb", + "metadata": {}, + "outputs": [], + "source": [ + "result = graph.search(\"esri\")" + ] + }, + { + "cell_type": "markdown", + "id": "c9bd3a74", + "metadata": {}, + "source": [ + "## Data Editing\n", + "\n", + "`apply_edits` consists of `adds`, `updates`, and `deletes` each of which takes a list of objects for the operation. These objects can be `Entity` or `Relationship`." + ] + }, + { + "cell_type": "markdown", + "id": "7dccad08", + "metadata": {}, + "source": [ + "### Adds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c26d193d", + "metadata": {}, + "outputs": [], + "source": [ + "add_entity = Entity(\n", + " type_name=\"Company\", \n", + " properties={\n", + " \"name\": \"Esri\",\n", + " \"year_established\": 1969\n", + " }\n", + ")\n", + "\n", + "add_relationship = Relationship(\n", + " type_name=\"WorksFor\", \n", + " origin_entity_id=\"{56BCCAF0-DD03-487A-BE39-F32164714190}\",\n", + " destination_entity_id=\"{26BCCAF0-DD03-484A-BE39-B32164718190}\",\n", + " properties={\n", + " \"startDate\": datetime(2020, 1, 6)\n", + " }\n", + ")\n", + "\n", + "graph.apply_edits(adds=[add_entity, add_relationship])" + ] + }, + { + "cell_type": "markdown", + "id": "43ac332f", + "metadata": {}, + "source": [ + "### Updates" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5a7dec51", + "metadata": {}, + "outputs": [], + "source": [ + "update_entity = Entity(\n", + " type_name=\"Company\", \n", + " id=\"{26BCCAF0-DD03-484A-BE39-B32164718190}\",\n", + " properties={\n", + " \"name\": \"Not Esri\",\n", + " \"shape\": Point(\n", + " {\n", + " \"x\":-89.86140978600001, \n", + " \"y\":38.902491682000004,\n", + " \"spatialReference\": {\"wkid\": 4326}\n", + " }\n", + " )\n", + " }\n", + ")\n", + "\n", + "graph.apply_edits(updates=[update_entity])" + ] + }, + { + "cell_type": "markdown", + "id": "9e29e1c7", + "metadata": {}, + "source": [ + "### Deletes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b0d29ff", + "metadata": {}, + "outputs": [], + "source": [ + "delete_entity = EntityDelete(\n", + " type_name=\"Company\", \n", + " ids=[\"{26BCCAF0-DD03-484A-BE39-B32164718190}\"]\n", + ")\n", + "\n", + "graph.apply_edits(deletes=[delete_entity], cascade_delete=True) # be sure to set cascade_delete to True to automatically delete relationships attached to the provided entity" + ] + }, + { + "cell_type": "markdown", + "id": "172a2f91", + "metadata": {}, + "source": [ + "## Data Model Editing" + ] + }, + { + "cell_type": "markdown", + "id": "8d4b8e99", + "metadata": {}, + "source": [ + "### Types" + ] + }, + { + "cell_type": "markdown", + "id": "71c007c9", + "metadata": {}, + "source": [ + "#### Adds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7a395b82", + "metadata": {}, + "outputs": [], + "source": [ + "# create the data model\n", + "graph.named_object_type_adds(\n", + " entity_types=[\n", + " EntityType(name=\"User\", properties={\"name\": GraphProperty(name=\"name\")}),\n", + " EntityType(name=\"Item\", properties={\n", + " \"id\": GraphProperty(name=\"id\"),\n", + " \"title\": GraphProperty(name=\"title\"),\n", + " \"type\": GraphProperty(name=\"type\")\n", + " })\n", + " ], \n", + " relationship_types=[\n", + " RelationshipType(name=\"DependsOn\"),\n", + " RelationshipType(name=\"Owns\")\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "38d7d06e", + "metadata": {}, + "source": [ + "#### Updates" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "02817a7b", + "metadata": {}, + "outputs": [], + "source": [ + "graph.named_object_type_update(\n", + " type_name=\"User\", \n", + " named_type_update=EntityType(name=\"User\", alias=\"NewUser\", strict=False), \n", + " mask=NamedObjectTypeMask(\n", + " update_alias=True,\n", + " update_strict=True\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "cd8e8922", + "metadata": {}, + "source": [ + "#### Deletes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c5fd2146", + "metadata": {}, + "outputs": [], + "source": [ + "graph.named_object_type_delete(type_name=\"User\")" + ] + }, + { + "cell_type": "markdown", + "id": "356cb157", + "metadata": {}, + "source": [ + "### Properties" + ] + }, + { + "cell_type": "markdown", + "id": "b0639d70", + "metadata": {}, + "source": [ + "#### Adds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6918fcd", + "metadata": {}, + "outputs": [], + "source": [ + "graph.graph_property_adds(\n", + " type_name=\"User\", \n", + " graph_properties=[\n", + " GraphProperty(name=\"name\"),\n", + " Graphproperty(name=\"post_count\", field_type=\"esriFieldTypeInteger\"),\n", + " GraphProperty(name=\"shape\", field_type=\"esriFieldTypeGeometry\", geometry_type=\"esriGeometryPoint\")\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "41405d8a", + "metadata": {}, + "source": [ + "#### Updates" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "091173c5", + "metadata": {}, + "outputs": [], + "source": [ + "graph.graph_property_update(\n", + " type_name=\"User\", \n", + " property_name=\"name\",\n", + " graph_property=GraphProperty(name=\"name\", alias=\"user_name\", field_type=\"esriFieldTypeString\"),\n", + " mask=GraphPropertyMask(\n", + " update_alias=True,\n", + " update_field_type=True\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "a0f6ac1f", + "metadata": {}, + "source": [ + "#### Deletes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4bcaed5d", + "metadata": {}, + "outputs": [], + "source": [ + "graph.graph_property_delete(type_name=\"User\", property_name=\"name\")" + ] + }, + { + "cell_type": "markdown", + "id": "230240c9", + "metadata": {}, + "source": [ + "### Search Indexes" + ] + }, + { + "cell_type": "markdown", + "id": "70ac44a7", + "metadata": {}, + "source": [ + "#### Adds" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1e25b609", + "metadata": {}, + "outputs": [], + "source": [ + "graph.update_search_index(adds={\"User\": SearchIndexProperties(property_names=[\"name\"])})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2834246", + "metadata": {}, + "outputs": [], + "source": [ + "# add search indexes to all text properties based on the data model\n", + "datamodel = graph.query_data_model()\n", + "for entity_type in datamodel.entity_types:\n", + " prop_list = []\n", + " for prop in datamodel.entity_types[entity_type].properties:\n", + " if datamodel.entity_types[entity_type].properties[prop].fieldType == 'esriFieldTypeString':\n", + " prop_list.append(prop)\n", + " knowledge_graph.update_search_index(adds={entity_type: SearchIndexProperties(property_names=prop_list)})\n", + "for entity_type in datamodel.relationship_types:\n", + " prop_list = []\n", + " for prop in datamodel.relationship_types[entity_type].properties:\n", + " if datamodel.relationship_types[entity_type].properties[prop].fieldType == 'esriFieldTypeString':\n", + " prop_list.append(prop)\n", + " knowledge_graph.update_search_index(adds={entity_type: SearchIndexProperties(property_names=prop_list)})" + ] + }, + { + "cell_type": "markdown", + "id": "501b002c", + "metadata": {}, + "source": [ + "#### Deletes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dcc7c86d", + "metadata": {}, + "outputs": [], + "source": [ + "graph.update_search_index(deletes={\"User\": SearchIndexProperties(property_names=[\"name\"])})" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From d5e63086664728c9ef02928935dbe263d0195509 Mon Sep 17 00:00:00 2001 From: Megan Banaski Date: Thu, 6 Feb 2025 08:03:40 -0800 Subject: [PATCH 2/3] KnowledgeGraph with as_dict update --- ...rt1_introduction_to_knowledge_graphs.ipynb | 182 ++----- .../part2_search_query_knowledge_graph.ipynb | 115 ++--- .../part3_edit_knowledge_graph.ipynb | 195 +++---- .../part4_using_graphclient.ipynb | 480 ------------------ 4 files changed, 173 insertions(+), 799 deletions(-) delete mode 100644 guide/17-working-with-knowledge-graphs/part4_using_graphclient.ipynb diff --git a/guide/17-working-with-knowledge-graphs/part1_introduction_to_knowledge_graphs.ipynb b/guide/17-working-with-knowledge-graphs/part1_introduction_to_knowledge_graphs.ipynb index 0791196d8b..14289a9226 100644 --- a/guide/17-working-with-knowledge-graphs/part1_introduction_to_knowledge_graphs.ipynb +++ b/guide/17-working-with-knowledge-graphs/part1_introduction_to_knowledge_graphs.ipynb @@ -166,143 +166,73 @@ "metadata": {}, "outputs": [], "source": [ - "knowledge_graph.datamodel" + "knowledge_graph.query_data_model(as_dict=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "The response from `datamodel` has many useful components that describe the schema of the knowledge graph. Important information to look for on the data model includes spatial reference, strictness, whether the service is arcgis managed, information on the unique identifier property, and search indexes. The data model also includes detailed information on each entity and relationship type.\n", + "The response from `query_data_model()` has many useful components that describe the schema of the knowledge graph. When `as_dict` is set to `False`, the response will be a `GraphDataModel`. Important information to look for on the data model includes spatial reference, strictness, whether the service is arcgis managed, information on the unique identifier property, and search indexes. The data model also includes detailed information on each entity and relationship type.\n", "\n", "```\n", - "{'data_model_timestamp': datetime.datetime(2023, 3, 22, 14, 4, 44, 432000),\n", - " 'spatial_reference': {'wkid': 4326},\n", - " 'entity_types': , # see below for more info on type dictionaries\n", - " 'relationship_types': , # see below for more info on type dictionaries\n", - " 'strict': False,\n", - " 'objectid_property': 'objectid',\n", - " 'globalid_property': 'globalid',\n", - " 'arcgis_managed': True,\n", - " 'identifier_info': {'identifier_mapping_info': {'uniform_property': {'identifier_property_name': 'globalid'}},\n", - " 'identifier_generation_info': {'uuid_method_hint': 'esriUUIDESRI'}},\n", - " 'search_indexes': {'esri__search_idx': {'name': 'esri__search_idx',\n", - " 'supported_category': 'Both',\n", - " 'analyzers': [{'name': 'text_en'}, {'name': 'identity'}],\n", - " 'search_properties': {'Document': {'property_names': ['metadata',\n", - " 'keywords',\n", - " 'fileExtension',\n", - " 'globalid',\n", - " 'name',\n", - " 'text',\n", - " 'title',\n", - " 'contentType',\n", - " 'url']},\n", - " 'HasDocument': {'property_names': ['globalid']},\n", - " 'Observation': {'property_names': ['quality_grade',\n", - " 'globalid',\n", - " 'time_observed',\n", - " 'description',\n", - " 'location',\n", - " 'observation_url',\n", - " 'photo_url',\n", - " 'species_guess',\n", - " 'most_disagree_with_identificati',\n", - " 'place_guess']},\n", - " 'Observed': {'property_names': ['globalid']},\n", - " 'ObservedIn': {'property_names': ['globalid']},\n", - " 'Reviewed': {'property_names': ['globalid']},\n", - " 'Species': {'property_names': ['taxon_common_name',\n", - " 'globalid',\n", - " 'taxon_name',\n", - " 'taxon_wikipedia',\n", - " 'taxon_photo_url']},\n", - " 'User': {'property_names': ['globalid', 'name', 'created_date']}}}}}\n", + "GraphDataModel(\n", + " data_model_timestamp=1737573982389, \n", + " spatial_reference={'wkid': 4326}, \n", + " entity_types=[\n", + " EntityType(\n", + " name='Vehicle', \n", + " alias='', \n", + " role='esriGraphNamedObjectRegular', \n", + " strict=False, \n", + " properties=[\n", + " GraphProperty(name='objectid', alias='objectid', domain='', field_type='esriFieldTypeOID', geometry_type=None, has_z=False, has_m=False, default_value=None, nullable=False, visible=True, editable=False, required=True, is_system_maintained=True, role='esriGraphPropertyRegular'), \n", + " GraphProperty(name='globalid', alias='globalid', domain='', field_type='esriFieldTypeGlobalID', geometry_type=None, has_z=False, has_m=False, default_value=None, nullable=False, visible=True, editable=False, required=True, is_system_maintained=True, role='esriGraphPropertyRegular'), \n", + " GraphProperty(name='make', alias='', domain='', field_type='esriFieldTypeString', geometry_type=None, has_z=False, has_m=False, default_value=None, nullable=True, visible=True, editable=True, required=False, is_system_maintained=False, role='esriGraphPropertyRegular')\n", + " ], \n", + " field_indexes=[\n", + " FieldIndex(name='esri__oid_idx', is_ascending=True, is_unique=True, fields=['objectid']), \n", + " FieldIndex(name='esri__globalid_idx', is_ascending=True, is_unique=True, fields=['globalid'])\n", + " ]\n", + " )\n", + " ],\n", + " search_indexes=[\n", + " SearchIndex(\n", + " name='esri__search_idx', \n", + " supported_category='both_entity_relationship', \n", + " analyzers=[SearchAnalyzer(name='text_en'), \n", + " SearchAnalyzer(name='identity')], \n", + " search_properties={\n", + " 'Document': SearchIndexProperties(property_names=['metadata', 'keywords', 'fileExtension', 'globalid', 'name', 'text', 'title', 'contentType', 'url']), \n", + " 'HasDocument': SearchIndexProperties(property_names=['globalid']), \n", + " 'Vehicle': SearchIndexProperties(property_names=['globalid', 'make'])\n", + " }\n", + " )\n", + " ], \n", + " provenance_source_type_values=ProvenanceSourceTypeValues(value_behavior_array=[]), \n", + " constraint_rules=[\n", + " RelationshipExclusionRule(name='HasDocumentRule', alias=\"Relationships of type 'HasDocument' can only have a destination entity of type 'Document'.\", disabled=False, role='esriGraphConstraintRuleRoleHasDocument', type='esriGraphRelationshipExclusionRuleType', origin_entity_types=SetOfNamedTypes(set=[], set_complement=[]), relationship_types=SetOfNamedTypes(set=['HasDocument'], set_complement=[]), destination_entity_types=SetOfNamedTypes(set=[], set_complement=['Document']))\n", + " ]\n", + ")\n", "```\n", "\n", "Entity and relationship types each have a format very similar to each other including basic information about the type like the name, role and strictness as well as properties and field indexes on the type. For a single type, this could look like:\n", "```\n", - "{'Company': {\n", - " 'name': 'Company',\n", - " 'alias': '',\n", - " 'role': 'esriGraphNamedObjectRegular',\n", - " 'strict': False,\n", - " 'properties': {\n", - " 'name': {\n", - " 'name': 'name',\n", - " 'alias': 'name',\n", - " 'fieldType': 'esriFieldTypeString',\n", - " 'hasZ': False,\n", - " 'hasM': False,\n", - " 'nullable': True,\n", - " 'editable': True,\n", - " 'visible': True,\n", - " 'required': False,\n", - " 'isSystemMaintained': False,\n", - " 'role': 'esriGraphPropertyRegular'\n", - " },\n", - " 'objectid': {\n", - " 'name': 'objectid',\n", - " 'alias': 'objectid',\n", - " 'fieldType': 'esriFieldTypeOID',\n", - " 'hasZ': False,\n", - " 'hasM': False,\n", - " 'nullable': False,\n", - " 'editable': False,\n", - " 'visible': True,\n", - " 'required': True,\n", - " 'isSystemMaintained': True,\n", - " 'role': 'esriGraphPropertyRegular'\n", - " },\n", - " 'globalid': {\n", - " 'name': 'globalid',\n", - " 'alias': 'globalid',\n", - " 'fieldType': 'esriFieldTypeGlobalID',\n", - " 'hasZ': False,\n", - " 'hasM': False,\n", - " 'nullable': False,\n", - " 'editable': False,\n", - " 'visible': True,\n", - " 'required': True,\n", - " 'isSystemMaintained': True,\n", - " 'role': 'esriGraphPropertyRegular'\n", - " },\n", - " 'shape': {\n", - " 'name': 'shape',\n", - " 'alias': 'shape',\n", - " 'fieldType': 'esriFieldTypeGeometry',\n", - " 'geometryType': 'esriGeometryPoint',\n", - " 'hasZ': False,\n", - " 'hasM': False,\n", - " 'nullable': True,\n", - " 'editable': True,\n", - " 'visible': True,\n", - " 'required': False,\n", - " 'isSystemMaintained': False,\n", - " 'role': 'esriGraphPropertyRegular'\n", - " }\n", - " },\n", - " 'field_indexes': {\n", - " 'esri__oid_idx': {\n", - " 'name': 'esri__oid_idx',\n", - " 'fields': ['objectid'],\n", - " 'isAscending': True,\n", - " 'isUnique': True\n", - " },\n", - " 'esri__globalid_idx': {\n", - " 'name': 'esri__globalid_idx',\n", - " 'fields': ['globalid'],\n", - " 'isAscending': True,\n", - " 'isUnique': True\n", - " },\n", - " 'esri__shape_geo_idx': {\n", - " 'name': 'esri__shape_geo_idx',\n", - " 'fields': ['shape'],\n", - " 'isAscending': True,\n", - " 'isUnique': False\n", - " }\n", - " }\n", - "}\n", + "EntityType(\n", + " name='Vehicle', \n", + " alias='', \n", + " role='esriGraphNamedObjectRegular', \n", + " strict=False, \n", + " properties=[\n", + " GraphProperty(name='objectid', alias='objectid', domain='', field_type='esriFieldTypeOID', geometry_type=None, has_z=False, has_m=False, default_value=None, nullable=False, visible=True, editable=False, required=True, is_system_maintained=True, role='esriGraphPropertyRegular'), \n", + " GraphProperty(name='globalid', alias='globalid', domain='', field_type='esriFieldTypeGlobalID', geometry_type=None, has_z=False, has_m=False, default_value=None, nullable=False, visible=True, editable=False, required=True, is_system_maintained=True, role='esriGraphPropertyRegular'), \n", + " GraphProperty(name='make', alias='', domain='', field_type='esriFieldTypeString', geometry_type=None, has_z=False, has_m=False, default_value=None, nullable=True, visible=True, editable=True, required=False, is_system_maintained=False, role='esriGraphPropertyRegular')\n", + " ], \n", + " field_indexes=[\n", + " FieldIndex(name='esri__oid_idx', is_ascending=True, is_unique=True, fields=['objectid']), \n", + " FieldIndex(name='esri__globalid_idx', is_ascending=True, is_unique=True, fields=['globalid'])\n", + " ]\n", + ")\n", "```" ] }, @@ -332,7 +262,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.16" + "version": "3.12.3" }, "vscode": { "interpreter": { diff --git a/guide/17-working-with-knowledge-graphs/part2_search_query_knowledge_graph.ipynb b/guide/17-working-with-knowledge-graphs/part2_search_query_knowledge_graph.ipynb index 215c5c6bc1..04b0a2641b 100644 --- a/guide/17-working-with-knowledge-graphs/part2_search_query_knowledge_graph.ipynb +++ b/guide/17-working-with-knowledge-graphs/part2_search_query_knowledge_graph.ipynb @@ -39,25 +39,29 @@ "metadata": {}, "outputs": [], "source": [ - "knowledge_graph.search(\"Esri\", category=\"entities\")" + "knowledge_graph.search(\"Esri\", category=\"entities\", as_dict=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "These results are in the form of a list of lists such as:\n", + "These results are a generator that can be accessed as a list such as:\n", "```\n", "[\n", - " [{'_objectType': 'entity',\n", - " '_typeName': 'Company',\n", - " '_id': UUID('f54c49c5-0aff-49ad-b38d-883b1323c709'),\n", - " '_properties': {\n", - " 'globalid': UUID('f54c49c5-0aff-49ad-b38d-883b1323c709'),\n", - " 'objectid': 2,\n", - " 'name': 'Esri'\n", - " }\n", - " }]\n", + " [\n", + " Entity(\n", + " properties={\n", + " 'employee_count': 5000, \n", + " 'product_count': 80, \n", + " 'name': 'Esri', \n", + " 'globalid': UUID('24bf1bdd-a17b-4140-aea8-fbc5701be7ea'), \n", + " 'established_on': 3600000, 'objectid': 1\n", + " }, \n", + " type_name='Company', \n", + " id=UUID('24bf1bdd-a17b-4140-aea8-fbc5701be7ea')\n", + " )\n", + " ]\n", "]\n", "```" ] @@ -69,53 +73,6 @@ "Search uses Lucene syntax, which allows for more advanced searches such as using a wildcard (*), searching a specific property (name:Esri), and boolean operators like AND and OR. For more information about Lucene syntax, [see the syntax guide from Apache](https://lucene.apache.org/core/2_9_4/queryparsersyntax.html)." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Query\n", - "\n", - "Querying the knowledge graph reaches out to the [query endpoint](https://developers.arcgis.com/rest/services-reference/enterprise/kgs-graph-query.htm) which runs the openCypher query on the graph and provides the results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "knowledge_graph.query(\"MATCH (n) RETURN n LIMIT 2\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "These results are in the form of a list of lists, such as:\n", - "```\n", - "[\n", - " [{'_objectType': 'entity',\n", - " '_typeName': 'Person',\n", - " '_id': UUID('33c1915e-2169-4a95-b07a-b141fc684a39'),\n", - " '_properties': {\n", - " 'globalid': UUID('33c1915e-2169-4a95-b07a-b141fc684a39'),\n", - " 'objectid': 1,\n", - " 'name': 'Megan'\n", - " }\n", - " }],\n", - " [{'_objectType': 'entity',\n", - " '_typeName': 'Company',\n", - " '_id': UUID('f54c49c5-0aff-49ad-b38d-883b1323c709'),\n", - " '_properties': {\n", - " 'globalid': UUID('f54c49c5-0aff-49ad-b38d-883b1323c709'),\n", - " 'objectid': 2,\n", - " 'name': 'Esri'\n", - " }\n", - " }]\n", - "]\n", - "```" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -125,6 +82,7 @@ "Query streaming accepts a query string the same way query does, but also allows the additional parameters:\n", "- 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", "- include_provenance, a boolean parameter used to determine whether provenance records will be returned as part of the query results.\n", + "- as_dict, a boolean parameter used to determine if results are returned as dictionaries or Entity/Relationship/Path objects. It is strongly recommended to use False and True will be removed in the future. The current default is True.\n", "\n", "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()." ] @@ -139,11 +97,11 @@ "\n", "# list example\n", "query_list = ['Megan', 'Emma', 'Cameron', 'Noah']\n", - "results = knowledge_graph.query_streaming(\"MATCH (p:Person) WHERE p.name IN $list RETURN p\", bind_param={\"list\": query_list})\n", + "results = knowledge_graph.query_streaming(\"MATCH (p:Person) WHERE p.name IN $list RETURN p\", bind_param={\"list\": query_list}, as_dict=False)\n", "\n", "# anonymous object example\n", "query_obj = {\"props\": {\"name\": \"Megan\"}, \"list\": ['Emma', 'Cameron', 'Noah']}\n", - "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})" + "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}, as_dict=False)" ] }, { @@ -183,7 +141,7 @@ "outputs": [], "source": [ "# including provenance in query results\n", - "results = knowledge_graph.query_streaming(\"MATCH (n:Provenance) RETURN n LIMIT 1\", include_provenance=True)\n", + "results = knowledge_graph.query_streaming(\"MATCH (n:Provenance) RETURN n LIMIT 1\", include_provenance=True, as_dict=False)\n", "list(results)" ] }, @@ -195,19 +153,19 @@ "```\n", "[\n", " [\n", - " {'_objectType': 'entity',\n", - " '_typeName': 'Provenance',\n", - " '_id': UUID('1794b6b2-4d91-48ad-b51f-5dfb80e58c01'),\n", - " '_properties': {'instanceID': UUID('3e16d8fe-7f68-45ef-805a-a54d78995411'),\n", - " 'propertyName': 'name',\n", - " 'sourceType': 'String',\n", - " 'typeName': 'Document',\n", - " 'globalid': UUID('1794b6b2-4d91-48ad-b51f-5dfb80e58c01'),\n", - " 'sourceName': 'MySourceName',\n", - " 'source': 'MySource',\n", - " 'objectid': 2\n", - " }\n", - " }\n", + " Entity(\n", + " properties={\n", + " 'instanceID': UUID('19a35172-0a3a-4372-91ee-9240aa36f925'), \n", + " 'propertyName': 'name', \n", + " 'sourceType': 'String', \n", + " 'typeName': 'Document', \n", + " 'globalid': UUID('fc9333d2-27e6-407e-a29f-04946e72a891'), \n", + " 'sourceName': 'MySourceName', \n", + " 'source': 'MySource', \n", + " 'objectid': 1}, \n", + " type_name='Provenance', \n", + " id=UUID('fc9333d2-27e6-407e-a29f-04946e72a891')\n", + " )\n", " ]\n", "]\n", "```" @@ -246,11 +204,12 @@ "import pandas as pd\n", "\n", "# openCypher query matches all entities (assume all entities returned are spatial for this example, OneType represents returning entities of a single type)\n", - "query_results = knowledge_graph.query(\"MATCH (n:OneType) RETURN n\")\n", + "query_results = knowledge_graph.query_streaming(\"MATCH (n:OneType) RETURN n\", as_dict=False)\n", + "query_results = list(query_results)\n", "\n", "# create a list of all properties of the type to use as columns of our data frame\n", "props_list = []\n", - "for prop in query_results[0][0]['_properties']:\n", + "for prop in query_results[0][0].properties:\n", " props_list.append(prop)\n", "\n", "# iterate through the results of the query, writing those results to a list to be used in the data frame\n", @@ -259,7 +218,7 @@ " single_result = []\n", " # write each property value to a list\n", " for prop in props_list:\n", - " single_result.append(result[0]['_properties'][prop])\n", + " single_result.append(result[0].properties[prop])\n", " # append the list of properties to the data list\n", " results_list.append(single_result)\n", "\n", @@ -292,7 +251,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.11" + "version": "3.12.3" }, "vscode": { "interpreter": { diff --git a/guide/17-working-with-knowledge-graphs/part3_edit_knowledge_graph.ipynb b/guide/17-working-with-knowledge-graphs/part3_edit_knowledge_graph.ipynb index 919ae4423b..2d5d0764f0 100644 --- a/guide/17-working-with-knowledge-graphs/part3_edit_knowledge_graph.ipynb +++ b/guide/17-working-with-knowledge-graphs/part3_edit_knowledge_graph.ipynb @@ -81,16 +81,15 @@ "metadata": {}, "outputs": [], "source": [ - "add_entity = {\n", - " \"_objectType\": \"entity\",\n", - " \"_typeName\": \"Company\",\n", - " \"_properties\": {\n", - " \"name\": \"Esri\", \n", + "add_entity = Entity(\n", + " type_name=\"Company\", \n", + " properties={\n", + " \"name\": \"Esri\",\n", " \"year_established\": 1969\n", " }\n", - "}\n", + ")\n", "\n", - "knowledge_graph.apply_edits(adds=[add_entity])" + "knowledge_graph.apply_edits(adds=[add_entity], as_dict=False)" ] }, { @@ -106,15 +105,16 @@ "metadata": {}, "outputs": [], "source": [ - "add_relationship = {\n", - " \"_objectType\": \"relationship\",\n", - " \"_typeName\": \"WorksFor\",\n", - " \"_originEntityId\": \"{56BCCAF0-DD03-487A-BE39-F32164714190}\",\n", - " \"_destinationEntityId\": \"{26BCCAF0-DD03-484A-BE39-B32164718190}\",\n", - " \"_properties\": {\"startDate\": datetime(2020, 1, 6)}\n", - "}\n", + "add_relationship = Relationship(\n", + " type_name=\"WorksFor\", \n", + " origin_entity_id=\"{56BCCAF0-DD03-487A-BE39-F32164714190}\",\n", + " destination_entity_id=\"{26BCCAF0-DD03-484A-BE39-B32164718190}\",\n", + " properties={\n", + " \"startDate\": datetime(2020, 1, 6)\n", + " }\n", + ")\n", "\n", - "knowledge_graph.apply_edits(adds=[add_relationship])" + "knowledge_graph.apply_edits(adds=[add_relationship], as_dict=False)" ] }, { @@ -132,20 +132,22 @@ "metadata": {}, "outputs": [], "source": [ - "update_entity = {\n", - " \"_objectType\": \"entity\",\n", - " \"_typeName\": \"Company\",\n", - " \"_id\": \"{26BCCAF0-DD03-484A-BE39-B32164718190}\",\n", - " \"_properties\": {\"name\": \"Not Esri\",\n", - " \"shape\": {\n", - " 'x': -89.86140978600001,\n", - " 'y': 38.902491682000004,\n", - " 'spatialReference': {'wkid': 4326},\n", - " '_objectType': 'geometry'}\n", - " }\n", - "}\n", + "update_entity = Entity(\n", + " type_name=\"Company\", \n", + " id=\"{26BCCAF0-DD03-484A-BE39-B32164718190}\",\n", + " properties={\n", + " \"name\": \"Not Esri\",\n", + " \"shape\": Point(\n", + " {\n", + " \"x\":-89.86140978600001, \n", + " \"y\":38.902491682000004,\n", + " \"spatialReference\": {\"wkid\": 4326}\n", + " }\n", + " )\n", + " }\n", + ")\n", "\n", - "knowledge_graph.apply_edits(updates=[update_entity])" + "knowledge_graph.apply_edits(updates=[update_entity], as_dict=False)" ] }, { @@ -163,13 +165,12 @@ "metadata": {}, "outputs": [], "source": [ - "delete_entity = {\n", - " \"_objectType\": \"entity\",\n", - " \"_typeName\": \"Company\",\n", - " \"_ids\": [\"{26BCCAF0-DD03-484A-BE39-B32164718190}\"]\n", - "}\n", + "delete_entity = EntityDelete(\n", + " type_name=\"Company\", \n", + " ids=[\"{26BCCAF0-DD03-484A-BE39-B32164718190}\"]\n", + ")\n", "\n", - "knowledge_graph.apply_edits(deletes=[delete_entity], cascade_delete=True) # be sure to set cascade_delete to True to automatically delete relationships attached to the provided entity" + "knowledge_graph.apply_edits(deletes=[delete_entity], cascade_delete=True, as_dict=False) # be sure to set cascade_delete to True to automatically delete relationships attached to the provided entity" ] }, { @@ -203,36 +204,19 @@ "source": [ "# create the data model\n", "knowledge_graph.named_object_type_adds(\n", - " entity_types=[{\n", - " \"name\": \"User\",\n", - " \"properties\": { # properties can either be created now or later using knowledge_graph.graph_property_adds() - more information below\n", - " \"name\": {\n", - " \"name\": \"name\",\n", - " \"role\": \"esriGraphPropertyRegular\"\n", - " }\n", - " }\n", - " },{\n", - " \"name\": \"Item\",\n", - " \"properties\": {\n", - " \"id\": {\n", - " \"name\": \"id\",\n", - " \"role\": \"esriGraphPropertyRegular\"\n", - " },\n", - " \"title\": {\n", - " \"name\": \"title\",\n", - " \"role\": \"esriGraphPropertyRegular\"\n", - " },\n", - " \"type\": {\n", - " \"name\": \"type\",\n", - " \"role\": \"esriGraphPropertyRegular\"\n", - " }\n", - " }\n", - " }], \n", - " relationship_types=[{\n", - " \"name\": \"Owns\"\n", - " },{\n", - " \"name\": \"DependsOn\"\n", - " }]\n", + " entity_types=[\n", + " EntityType(name=\"User\", properties={\"name\": GraphProperty(name=\"name\")}),\n", + " EntityType(name=\"Item\", properties={\n", + " \"id\": GraphProperty(name=\"id\"),\n", + " \"title\": GraphProperty(name=\"title\"),\n", + " \"type\": GraphProperty(name=\"type\")\n", + " })\n", + " ], \n", + " relationship_types=[\n", + " RelationshipType(name=\"DependsOn\"),\n", + " RelationshipType(name=\"Owns\")\n", + " ],\n", + " as_dict=False\n", ")" ] }, @@ -253,14 +237,12 @@ "source": [ "knowledge_graph.named_object_type_update(\n", " type_name=\"User\", \n", - " named_type_update={\n", - " \"name\": \"User\",\n", - " \"alias\": \"NewUser\",\n", - " \"role\": \"esriGraphNamedObjectRegular\",\n", - " \"strict\": False\n", - " }, mask={\n", - " \"update_alias\": True\n", - " }\n", + " named_type_update=EntityType(name=\"User\", alias=\"NewUser\", strict=False), \n", + " mask=NamedObjectTypeMask(\n", + " update_alias=True,\n", + " update_strict=True\n", + " ),\n", + " as_dict=False\n", ")" ] }, @@ -279,7 +261,7 @@ "metadata": {}, "outputs": [], "source": [ - "knowledge_graph.named_object_type_delete(\"User\")" + "knowledge_graph.named_object_type_delete(type_name=\"User\", as_dict=False)" ] }, { @@ -327,18 +309,11 @@ "source": [ "knowledge_graph.graph_property_adds(\n", " type_name=\"User\", \n", - " graph_properties=[{\n", - " \"name\": \"name\",\n", - " \"role\": \"esriGraphPropertyRegular\"\n", - " },{\n", - " \"name\": \"post_count\",\n", - " \"fieldType\": \"esriFieldTypeInteger\",\n", - " \"role\": \"esriGraphPropertyRegular\"\n", - " },{\n", - " \"name\": \"shape\",\n", - " \"fieldtype\": \"esriFieldTypeGeometry\",\n", - " \"geometryType\": \"esriGeometryPoint\"\n", - " }]\n", + " graph_properties=[\n", + " GraphProperty(name=\"name\"),\n", + " Graphproperty(name=\"post_count\", field_type=\"esriFieldTypeInteger\"),\n", + " GraphProperty(name=\"shape\", field_type=\"esriFieldTypeGeometry\", geometry_type=\"esriGeometryPoint\")\n", + " ]\n", ")" ] }, @@ -359,15 +334,13 @@ "source": [ "knowledge_graph.graph_property_update(\n", " type_name=\"User\", \n", - " graph_property=\"name\", \n", - " property_update={\n", - " \"name\": \"name\",\n", - " \"alias\": \"user_name\",\n", - " \"role\": \"esriGraphPropertyRegular\"\n", - " },\n", - " mask={\n", - " \"update_alias\": True\n", - " }\n", + " property_name=\"name\",\n", + " graph_property=GraphProperty(name=\"name\", alias=\"user_name\", field_type=\"esriFieldTypeString\"),\n", + " mask=GraphPropertyMask(\n", + " update_alias=True,\n", + " update_field_type=True\n", + " ),\n", + " as_dict=False\n", ")" ] }, @@ -386,7 +359,7 @@ "metadata": {}, "outputs": [], "source": [ - "knowledge_graph.graph_property_delete(\"User\", \"name\")" + "graph.graph_property_delete(type_name=\"User\", property_name=\"name\", as_dict=False)" ] }, { @@ -410,33 +383,25 @@ "outputs": [], "source": [ "# add search indexes to individual properties\n", - "knowledge_graph.update_search_index(adds={\n", - " \"User\": {\n", - " \"property_names\": [\"name\"]\n", - " }\n", - "})\n", + "knowledge_graph.update_search_index(adds={\"User\": SearchIndexProperties(property_names=[\"name\"])}, as_dict=False)\n", "\n", "# add search indexes to all text properties based on the data model\n", - "datamodel = knowledge_graph.datamodel\n", - "for entity_type in datamodel['entity_types']:\n", + "datamodel = knowledge_graph.query_data_model()\n", + "for entity_type in datamodel.entity_types:\n", " prop_list = []\n", - " for prop in datamodel['entity_types'][entity_type]['properties']:\n", - " if datamodel['entity_types'][entity_type]['properties'][prop]['fieldType'] == 'esriFieldTypeString':\n", + " for prop in datamodel.entity_types[entity_type].properties:\n", + " if datamodel.entity_types[entity_type].properties[prop].fieldType == 'esriFieldTypeString':\n", " prop_list.append(prop)\n", - " knowledge_graph.update_search_index(adds={entity_type: {\"property_names\": prop_list}})\n", - "for entity_type in datamodel['relationship_types']:\n", + " knowledge_graph.update_search_index(adds={entity_type: SearchIndexProperties(property_names=prop_list)}, as_dict=False)\n", + "for entity_type in datamodel.relationship_types:\n", " prop_list = []\n", - " for prop in datamodel['relationship_types'][entity_type]['properties']:\n", - " if datamodel['relationship_types'][entity_type]['properties'][prop]['fieldType'] == 'esriFieldTypeString':\n", + " for prop in datamodel.relationship_types[entity_type].properties:\n", + " if datamodel.relationship_types[entity_type].properties[prop].fieldType == 'esriFieldTypeString':\n", " prop_list.append(prop)\n", - " knowledge_graph.update_search_index(adds={entity_type: {\"property_names\": prop_list}})\n", + " knowledge_graph.update_search_index(adds={entity_type: SearchIndexProperties(property_names=prop_list)}, as_dict=False)\n", "\n", "# delete a property from the search index\n", - "knowledge_graph.update_search_index(deletes={\n", - " \"User\": {\n", - " \"property_names\": [\"name\"]\n", - " }\n", - "})" + "knowledge_graph.update_search_index(deletes={\"User\": SearchIndexProperties(property_names=[\"name\"])}, as_dict=False)" ] } ], @@ -456,7 +421,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.12.3" }, "vscode": { "interpreter": { diff --git a/guide/17-working-with-knowledge-graphs/part4_using_graphclient.ipynb b/guide/17-working-with-knowledge-graphs/part4_using_graphclient.ipynb deleted file mode 100644 index ac30c7e45f..0000000000 --- a/guide/17-working-with-knowledge-graphs/part4_using_graphclient.ipynb +++ /dev/null @@ -1,480 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "266912f3", - "metadata": {}, - "source": [ - "# Using GraphClient" - ] - }, - { - "cell_type": "markdown", - "id": "aa15c594", - "metadata": {}, - "source": [ - "

Table of Contents

\n", - "
\n", - " \n", - "
" - ] - }, - { - "cell_type": "markdown", - "id": "7f686a14", - "metadata": {}, - "source": [ - "## Introduction\n", - "\n", - "`GraphClient` provides classes for common things like `EntityType`, `RelationshipType`, `Entity`, `Relationship`, `GraphProperty` and more. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e7479baa", - "metadata": {}, - "outputs": [], - "source": [ - "from arcgis.gis import GIS\n", - "from arcgis.geometry import Point\n", - "from arcgis.graph import GraphClient, EntityType, RelationshipType, Entity, Relationship, GraphProperty, EntityDelete, NamedObjectTypeMask, GraphPropertyMask, SearchIndexProperties\n", - "\n", - "gis = GIS(\"home\")\n", - "new_service = gis.content.create_service(\n", - " name=\"MyKnowledgeGraph\",\n", - " capabilities=\"Query,Editing,Create,Update,Delete\",\n", - " service_type=\"KnowledgeGraph\"\n", - ")\n", - "graph = GraphClient(new_service.url, gis=gis)" - ] - }, - { - "cell_type": "markdown", - "id": "624705dc", - "metadata": {}, - "source": [ - "## Query\n", - "\n", - "`query` in `GraphClient` will execute a `query_streaming` and provides extra query options such as using `bind_param` to define bind parameters to be used in the query and `include_provenance` which will query for provenance records if set to `True`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fe50ad2e", - "metadata": {}, - "outputs": [], - "source": [ - "result = graph.query(\"MATCH (n) RETURN n LIMIT 5\")\n", - "list(result)" - ] - }, - { - "cell_type": "markdown", - "id": "6e7f0335", - "metadata": {}, - "source": [ - "## Search\n", - "\n", - "`search` searches the graph for the given string on any properties of both entities or relationships by default. To search for properties on only entities or only relationships you can use the `category` parameter on `search` and set the value to either `entities`, `relationships`, or `both` (default)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1fba59eb", - "metadata": {}, - "outputs": [], - "source": [ - "result = graph.search(\"esri\")" - ] - }, - { - "cell_type": "markdown", - "id": "c9bd3a74", - "metadata": {}, - "source": [ - "## Data Editing\n", - "\n", - "`apply_edits` consists of `adds`, `updates`, and `deletes` each of which takes a list of objects for the operation. These objects can be `Entity` or `Relationship`." - ] - }, - { - "cell_type": "markdown", - "id": "7dccad08", - "metadata": {}, - "source": [ - "### Adds" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c26d193d", - "metadata": {}, - "outputs": [], - "source": [ - "add_entity = Entity(\n", - " type_name=\"Company\", \n", - " properties={\n", - " \"name\": \"Esri\",\n", - " \"year_established\": 1969\n", - " }\n", - ")\n", - "\n", - "add_relationship = Relationship(\n", - " type_name=\"WorksFor\", \n", - " origin_entity_id=\"{56BCCAF0-DD03-487A-BE39-F32164714190}\",\n", - " destination_entity_id=\"{26BCCAF0-DD03-484A-BE39-B32164718190}\",\n", - " properties={\n", - " \"startDate\": datetime(2020, 1, 6)\n", - " }\n", - ")\n", - "\n", - "graph.apply_edits(adds=[add_entity, add_relationship])" - ] - }, - { - "cell_type": "markdown", - "id": "43ac332f", - "metadata": {}, - "source": [ - "### Updates" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5a7dec51", - "metadata": {}, - "outputs": [], - "source": [ - "update_entity = Entity(\n", - " type_name=\"Company\", \n", - " id=\"{26BCCAF0-DD03-484A-BE39-B32164718190}\",\n", - " properties={\n", - " \"name\": \"Not Esri\",\n", - " \"shape\": Point(\n", - " {\n", - " \"x\":-89.86140978600001, \n", - " \"y\":38.902491682000004,\n", - " \"spatialReference\": {\"wkid\": 4326}\n", - " }\n", - " )\n", - " }\n", - ")\n", - "\n", - "graph.apply_edits(updates=[update_entity])" - ] - }, - { - "cell_type": "markdown", - "id": "9e29e1c7", - "metadata": {}, - "source": [ - "### Deletes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3b0d29ff", - "metadata": {}, - "outputs": [], - "source": [ - "delete_entity = EntityDelete(\n", - " type_name=\"Company\", \n", - " ids=[\"{26BCCAF0-DD03-484A-BE39-B32164718190}\"]\n", - ")\n", - "\n", - "graph.apply_edits(deletes=[delete_entity], cascade_delete=True) # be sure to set cascade_delete to True to automatically delete relationships attached to the provided entity" - ] - }, - { - "cell_type": "markdown", - "id": "172a2f91", - "metadata": {}, - "source": [ - "## Data Model Editing" - ] - }, - { - "cell_type": "markdown", - "id": "8d4b8e99", - "metadata": {}, - "source": [ - "### Types" - ] - }, - { - "cell_type": "markdown", - "id": "71c007c9", - "metadata": {}, - "source": [ - "#### Adds" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7a395b82", - "metadata": {}, - "outputs": [], - "source": [ - "# create the data model\n", - "graph.named_object_type_adds(\n", - " entity_types=[\n", - " EntityType(name=\"User\", properties={\"name\": GraphProperty(name=\"name\")}),\n", - " EntityType(name=\"Item\", properties={\n", - " \"id\": GraphProperty(name=\"id\"),\n", - " \"title\": GraphProperty(name=\"title\"),\n", - " \"type\": GraphProperty(name=\"type\")\n", - " })\n", - " ], \n", - " relationship_types=[\n", - " RelationshipType(name=\"DependsOn\"),\n", - " RelationshipType(name=\"Owns\")\n", - " ]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "38d7d06e", - "metadata": {}, - "source": [ - "#### Updates" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "02817a7b", - "metadata": {}, - "outputs": [], - "source": [ - "graph.named_object_type_update(\n", - " type_name=\"User\", \n", - " named_type_update=EntityType(name=\"User\", alias=\"NewUser\", strict=False), \n", - " mask=NamedObjectTypeMask(\n", - " update_alias=True,\n", - " update_strict=True\n", - " )\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "cd8e8922", - "metadata": {}, - "source": [ - "#### Deletes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c5fd2146", - "metadata": {}, - "outputs": [], - "source": [ - "graph.named_object_type_delete(type_name=\"User\")" - ] - }, - { - "cell_type": "markdown", - "id": "356cb157", - "metadata": {}, - "source": [ - "### Properties" - ] - }, - { - "cell_type": "markdown", - "id": "b0639d70", - "metadata": {}, - "source": [ - "#### Adds" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e6918fcd", - "metadata": {}, - "outputs": [], - "source": [ - "graph.graph_property_adds(\n", - " type_name=\"User\", \n", - " graph_properties=[\n", - " GraphProperty(name=\"name\"),\n", - " Graphproperty(name=\"post_count\", field_type=\"esriFieldTypeInteger\"),\n", - " GraphProperty(name=\"shape\", field_type=\"esriFieldTypeGeometry\", geometry_type=\"esriGeometryPoint\")\n", - " ]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "41405d8a", - "metadata": {}, - "source": [ - "#### Updates" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "091173c5", - "metadata": {}, - "outputs": [], - "source": [ - "graph.graph_property_update(\n", - " type_name=\"User\", \n", - " property_name=\"name\",\n", - " graph_property=GraphProperty(name=\"name\", alias=\"user_name\", field_type=\"esriFieldTypeString\"),\n", - " mask=GraphPropertyMask(\n", - " update_alias=True,\n", - " update_field_type=True\n", - " )\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "a0f6ac1f", - "metadata": {}, - "source": [ - "#### Deletes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4bcaed5d", - "metadata": {}, - "outputs": [], - "source": [ - "graph.graph_property_delete(type_name=\"User\", property_name=\"name\")" - ] - }, - { - "cell_type": "markdown", - "id": "230240c9", - "metadata": {}, - "source": [ - "### Search Indexes" - ] - }, - { - "cell_type": "markdown", - "id": "70ac44a7", - "metadata": {}, - "source": [ - "#### Adds" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1e25b609", - "metadata": {}, - "outputs": [], - "source": [ - "graph.update_search_index(adds={\"User\": SearchIndexProperties(property_names=[\"name\"])})" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d2834246", - "metadata": {}, - "outputs": [], - "source": [ - "# add search indexes to all text properties based on the data model\n", - "datamodel = graph.query_data_model()\n", - "for entity_type in datamodel.entity_types:\n", - " prop_list = []\n", - " for prop in datamodel.entity_types[entity_type].properties:\n", - " if datamodel.entity_types[entity_type].properties[prop].fieldType == 'esriFieldTypeString':\n", - " prop_list.append(prop)\n", - " knowledge_graph.update_search_index(adds={entity_type: SearchIndexProperties(property_names=prop_list)})\n", - "for entity_type in datamodel.relationship_types:\n", - " prop_list = []\n", - " for prop in datamodel.relationship_types[entity_type].properties:\n", - " if datamodel.relationship_types[entity_type].properties[prop].fieldType == 'esriFieldTypeString':\n", - " prop_list.append(prop)\n", - " knowledge_graph.update_search_index(adds={entity_type: SearchIndexProperties(property_names=prop_list)})" - ] - }, - { - "cell_type": "markdown", - "id": "501b002c", - "metadata": {}, - "source": [ - "#### Deletes" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dcc7c86d", - "metadata": {}, - "outputs": [], - "source": [ - "graph.update_search_index(deletes={\"User\": SearchIndexProperties(property_names=[\"name\"])})" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 09bcef2f8aadd4d7ef0b9037acf5d86bf2b08fca Mon Sep 17 00:00:00 2001 From: Megan Banaski Date: Tue, 6 May 2025 12:44:56 -0500 Subject: [PATCH 3/3] link updates --- ...art1_introduction_to_knowledge_graphs.ipynb | 4 ++-- .../part2_search_query_knowledge_graph.ipynb | 4 ++-- .../part3_edit_knowledge_graph.ipynb | 18 +++++++++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/guide/17-working-with-knowledge-graphs/part1_introduction_to_knowledge_graphs.ipynb b/guide/17-working-with-knowledge-graphs/part1_introduction_to_knowledge_graphs.ipynb index 14289a9226..30b04b7776 100644 --- a/guide/17-working-with-knowledge-graphs/part1_introduction_to_knowledge_graphs.ipynb +++ b/guide/17-working-with-knowledge-graphs/part1_introduction_to_knowledge_graphs.ipynb @@ -61,7 +61,7 @@ "source": [ "## Connect\n", "\n", - "Using the ArcGIS API for Python, you can connect to a `KnowledgeGraph` with `arcgis.graph`:" + "Using the ArcGIS API for Python, you can connect to a [`KnowledgeGraph`](https://developers.arcgis.com/python/latest/api-reference/arcgis.graph.html#knowledgegraph) with [`arcgis.graph`](https://developers.arcgis.com/python/latest/api-reference/arcgis.graph.html):" ] }, { @@ -90,7 +90,7 @@ "metadata": {}, "source": [ "## Create\n", - "Using the ArcGIS API for Python, you can create a new Knowledge Graph using [create_service()](https://developers.arcgis.com/python/api-reference/arcgis.gis.toc.html#arcgis.gis.ContentManager.create_service)." + "Using the ArcGIS API for Python, you can create a new Knowledge Graph using [`create_service()`](https://developers.arcgis.com/python/api-reference/arcgis.gis.toc.html#arcgis.gis.ContentManager.create_service)." ] }, { diff --git a/guide/17-working-with-knowledge-graphs/part2_search_query_knowledge_graph.ipynb b/guide/17-working-with-knowledge-graphs/part2_search_query_knowledge_graph.ipynb index 04b0a2641b..827ab4e998 100644 --- a/guide/17-working-with-knowledge-graphs/part2_search_query_knowledge_graph.ipynb +++ b/guide/17-working-with-knowledge-graphs/part2_search_query_knowledge_graph.ipynb @@ -26,7 +26,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "There are a couple different ways to access the data of the knowledge graph. `search` provides results based on a full-text search string. `query` provides results based on an openCypher query string. The goal of this guide is to provide examples of various searches and queries that could be performed on a knowledge graph.\n", + "There are a couple different ways to access the data of the knowledge graph. [`search`](https://developers.arcgis.com/python/latest/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.search) provides results based on a full-text search string. [`query_streaming`](https://developers.arcgis.com/python/latest/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.query_streaming) provides results based on an openCypher query string. The goal of this guide is to provide examples of various searches and queries that could be performed on a knowledge graph.\n", "\n", "## Search\n", "\n", @@ -82,7 +82,7 @@ "Query streaming accepts a query string the same way query does, but also allows the additional parameters:\n", "- 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", "- include_provenance, a boolean parameter used to determine whether provenance records will be returned as part of the query results.\n", - "- as_dict, a boolean parameter used to determine if results are returned as dictionaries or Entity/Relationship/Path objects. It is strongly recommended to use False and True will be removed in the future. The current default is True.\n", + "- as_dict, a boolean parameter used to determine if results are returned as dictionaries or [Entity](https://developers.arcgis.com/python/latest/api-reference/arcgis.graph.html#entity)/[Relationship](https://developers.arcgis.com/python/latest/api-reference/arcgis.graph.html#relationship)/[Path](https://developers.arcgis.com/python/latest/api-reference/arcgis.graph.html#path) objects. It is strongly recommended to use False and True will be removed in the future. The current default is True.\n", "\n", "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()." ] diff --git a/guide/17-working-with-knowledge-graphs/part3_edit_knowledge_graph.ipynb b/guide/17-working-with-knowledge-graphs/part3_edit_knowledge_graph.ipynb index 2d5d0764f0..f157935db6 100644 --- a/guide/17-working-with-knowledge-graphs/part3_edit_knowledge_graph.ipynb +++ b/guide/17-working-with-knowledge-graphs/part3_edit_knowledge_graph.ipynb @@ -51,7 +51,7 @@ "source": [ "## Introduction\n", "\n", - "The ArcGIS API for Python allows editing of both the data and data model of the `KnowledgeGraph`. The goal of this guide is to provide information and examples of how to edit your knowledge graphs using python.\n", + "The ArcGIS API for Python allows editing of both the data and data model of the [`KnowledgeGraph`](https://developers.arcgis.com/python/latest/api-reference/arcgis.graph.html#knowledgegraph). The goal of this guide is to provide information and examples of how to edit your knowledge graphs using python.\n", "\n", "Editing the data will allow for:\n", "- Creating and deleting entities\n", @@ -69,7 +69,7 @@ "metadata": {}, "source": [ "## Data Editing\n", - "All data editing is accomplished using [knowledge_graph.apply_edits()](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.apply_edits)\n", + "All data editing is accomplished using [`knowledge_graph.apply_edits()`](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.apply_edits)\n", "### Adds\n", "\n", "To add an entity to the knowledge graph, we define the type and properties of the entity:" @@ -193,7 +193,7 @@ "source": [ "#### Adds\n", "\n", - "Adding new types involves forming the type objects and pushing them into the data model of the knowledge graph using [knowledge_graph.named_object_type_adds()](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.named_object_type_adds). Named types (entity and relationship types) can be created in bulk or individually as needed. The following example shows creating these named types all at the same time:" + "Adding new types involves forming the type objects and pushing them into the data model of the knowledge graph using [`knowledge_graph.named_object_type_adds()`](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.named_object_type_adds). Named types (entity and relationship types) can be created in bulk or individually as needed. The following example shows creating these named types all at the same time:" ] }, { @@ -226,7 +226,7 @@ "source": [ "#### Updates\n", "\n", - "Updates are performed on named object types using [knowledge_graph.named_object_type_update()](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.named_object_type_update). Updating the name of a type is not allowed." + "Updates are performed on named object types using [`knowledge_graph.named_object_type_update()`](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.named_object_type_update). Updating the name of a type is not allowed." ] }, { @@ -252,7 +252,7 @@ "source": [ "#### Deletes\n", "\n", - "Deleting types is as simple as passing the string name of the type to [knowledge_graph.named_object_type_delete()](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.named_object_type_delete)" + "Deleting types is as simple as passing the string name of the type to [`knowledge_graph.named_object_type_delete()`](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.named_object_type_delete)" ] }, { @@ -277,7 +277,7 @@ "source": [ "#### Adds\n", "\n", - "Properties can be added to named types at any point using [knowledge_graph.graph_property_adds()](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.graph_property_adds). Many properties can be added to a given type in a single call.\n", + "Properties can be added to named types at any point using [`knowledge_graph.graph_property_adds()`](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.graph_property_adds). Many properties can be added to a given type in a single call.\n", "\n", "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", "- esriFieldTypeSmallInteger\n", @@ -323,7 +323,7 @@ "source": [ "#### Updates\n", "\n", - "Information about the properties on a type can be updated using [knowledge_graph.graph_property_update()](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.graph_property_update). Only one property of a given type can be updated in a single call." + "Information about the properties on a type can be updated using [`knowledge_graph.graph_property_update()`](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.graph_property_update). Only one property of a given type can be updated in a single call." ] }, { @@ -350,7 +350,7 @@ "source": [ "#### Deletes\n", "\n", - "Deleting a property is a very simple, just pass the name of the type and property to be deleted using [knowledge_graph.graph_property_delete()](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.graph_property_delete). Only one property from any given type can be deleted in a single call. To delete multiple properties, it may be good to loop through a list of properties you plan to delete or make multiple calls consecutively." + "Deleting a property is a very simple, just pass the name of the type and property to be deleted using [`knowledge_graph.graph_property_delete()`](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.graph_property_delete). Only one property from any given type can be deleted in a single call. To delete multiple properties, it may be good to loop through a list of properties you plan to delete or make multiple calls consecutively." ] }, { @@ -373,7 +373,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Search indexes can be added to esriFieldTypeString properties to allow the contents of those properties to be searched for when using [knowledge_graph.search()](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.search)." + "`esriFieldTypeString` properties can be added to the [`SearchIndex`](https://developers.arcgis.com/python/latest/api-reference/arcgis.graph.html#searchindex) to allow the contents of those properties to be searched for when using [`knowledge_graph.search()`](https://developers.arcgis.com/python/api-reference/arcgis.graph.html#arcgis.graph.KnowledgeGraph.search)." ] }, {