Exception | Description |
---|---|
ArcGIS.Core.CalledOnWrongThreadException | This method or property must be called within the lambda passed to QueuedTask.Run. |
//On the QueuedTask... //and assuming you have established a connection to a knowledge graph //... //Construct an openCypher query - return the first 10 entities (whatever //they are...) var query = "MATCH (n) RETURN n LIMIT 10";//default limit is 100 if not specified //other examples... //query = "MATCH (a:Person) RETURN [a.name, a.age] ORDER BY a.age DESC LIMIT 50"; //query = "MATCH (b:Person) RETURN { Xperson: { Xname: b.name, Xage: b.age } } ORDER BY b.name DESC"; //query = "MATCH p = (c:Person)-[:HasCar]-() RETURN p ORDER BY c.name DESC"; //Create a query filter //Note: OutputSpatialReference is currently ignored var kg_qf = new KnowledgeGraphQueryFilter() { QueryText = query }; //Optionally - u can choose to include provenance in the results //(_if_ the KG has provenance - otherwise the query will fail) if (includeProvenanceIfPresent) { //see "Get Whether KG Supports Provenance" snippet if (KnowledgeGraphSupportsProvenance(kg)) { //Only include if the KG has provenance kg_qf.ProvenanceBehavior = KnowledgeGraphProvenanceBehavior.Include;//default is exclude } } //submit the query - returns a KnowledgeGraphCursor using (var kg_rc = kg.SubmitQuery(kg_qf)) { //wait for rows to be returned from the server //note the "await"... while (await kg_rc.WaitForRowsAsync()) { //Rows have been retrieved - process this "batch"... while (kg_rc.MoveNext()) { //Get the current KnowledgeGraphRow using (var graph_row = kg_rc.Current) { //Graph row is an array, process all returned values... var val_count = (int)graph_row.GetCount(); for (int i = 0; i < val_count; i++) { var retval = graph_row[i]; //Process row value (note: recursive) //See "Process a KnowledgeGraphRow Value" snippet ProcessKnowledgeGraphRowValue(retval); } } } }//WaitForRowsAsync }//SubmitQuery
//On the QueuedTask... //and assuming you have established a connection to a knowledge graph //... //Construct a KG search filter. Search text uses Apache Lucene Query Parser //syntax - https://lucene.apache.org/core/2_9_4/queryparsersyntax.html var kg_sf = new KnowledgeGraphSearchFilter() { SearchTarget = KnowledgeGraphNamedTypeCategory.Entity, SearchText = "Acme Electric Co.", ReturnSearchContext = true, MaxRowCount = 10 //Default is 100 if not specified }; //submit the search - returns a KnowledgeGraphCursor var e = 0; using (var kg_rc = kg.SubmitSearch(kg_sf)) { //wait for rows to be returned from the server //note the "await"... while (await kg_rc.WaitForRowsAsync()) { //Rows have been retrieved - process this "batch"... while (kg_rc.MoveNext()) { //Get the current KnowledgeGraphRow using (var graph_row = kg_rc.Current) { //We are returning entities from this search var entity = graph_row[0] as KnowledgeGraphEntityValue; var entity_type = entity.GetTypeName(); var record = new List<string>(); //discover keys(aka "fields") dynamically via GetKeys foreach (var prop_name in entity.GetKeys()) { var obj_val = entity[prop_name] ?? "null"; record.Add(obj_val.ToString()); } System.Diagnostics.Debug.WriteLine( $"{entity_type}[{e++}] " + string.Join(", ", record)); //or use "Process a KnowledgeGraphRow Value" snippet //ProcessKnowledgeGraphRowValue(entity); } } }//WaitForRowsAsync }//SubmitSearch
//Base class for entities and relationships //(including documents and provenance) public void ProcessGraphNamedObjectValue( KnowledgeGraphNamedObjectValue kg_named_obj_val) { if (kg_named_obj_val is KnowledgeGraphEntityValue kg_entity) { var label = kg_entity.GetLabel(); //TODO - use label } else if (kg_named_obj_val is KnowledgeGraphRelationshipValue kg_rel) { var has_entity_ids = kg_rel.GetHasRelatedEntityIDs(); if (kg_rel.GetHasRelatedEntityIDs()) { var origin_id = kg_rel.GetOriginID(); var dest_id = kg_rel.GetDestinationID(); //TODO - use ids } } var id = kg_named_obj_val.GetID(); var oid = kg_named_obj_val.GetObjectID(); //Note: Typename corresponds to the name of the feature class or table //in the relational gdb model -and- to the name of the KnowledgeGraphNamedObjectType //in the knowledge graph data model var type_name = kg_named_obj_val.GetTypeName(); //TODO use id, object id, etc. } //Object values include entities, relationships, and anonymous objects public void ProcessGraphObjectValue(KnowledgeGraphObjectValue kg_obj_val) { switch (kg_obj_val) { case KnowledgeGraphEntityValue kg_entity: ProcessGraphNamedObjectValue(kg_entity); break; case KnowledgeGraphRelationshipValue kg_rel: ProcessGraphNamedObjectValue(kg_rel); break; default: //Anonymous objects break; } //graph object values have a set of properties (equivalent //to a collection of key/value pairs) var keys = kg_obj_val.GetKeys(); foreach (var key in keys) ProcessKnowledgeGraphRowValue(kg_obj_val[key]);//Recurse } //Process a KnowledgeGraphValue from a query or search public void ProcessGraphValue(KnowledgeGraphValue kg_val) { switch (kg_val) { case KnowledgeGraphPrimitiveValue kg_prim: //KnowledgeGraphPrimitiveValue not currently used in //query and search ProcessKnowledgeGraphRowValue(kg_prim.GetValue());//Recurse return; case KnowledgeGraphArrayValue kg_array: var count = kg_array.GetSize(); //Recursively process each value in the array for (ulong i = 0; i < count; i++) ProcessKnowledgeGraphRowValue(kg_array[i]);//Recurse return; case KnowledgeGraphPathValue kg_path: //Entities var entity_count = kg_path.GetEntityCount(); //Recursively process each entity value in the path for (ulong i = 0; i < entity_count; i++) ProcessGraphObjectValue(kg_path.GetEntity(i));//Recurse //Recursively process each relationship value in the path var relate_count = kg_path.GetRelationshipCount(); for (ulong i = 0; i < relate_count; i++) ProcessGraphObjectValue(kg_path.GetRelationship(i));//Recurse return; case KnowledgeGraphObjectValue kg_object: ProcessGraphObjectValue(kg_object);//Recurse return; default: var type_string = kg_val.GetType().ToString(); System.Diagnostics.Debug.WriteLine( $"Unknown: '{type_string}'"); return; } } //Process each value from the KnowledgeGraphRow array public void ProcessKnowledgeGraphRowValue(object value) { switch (value) { //Graph value? case KnowledgeGraphValue kg_val: var kg_type = kg_val.KnowledgeGraphValueType.ToString(); System.Diagnostics.Debug.WriteLine( $"KnowledgeGraphValue: '{kg_type}'"); ProcessGraphValue(kg_val);//Recurse return; //Primitive types...add additional logic as needed case System.DBNull dbn: System.Diagnostics.Debug.WriteLine("DBNull.Value"); return; case string str: System.Diagnostics.Debug.WriteLine($"'{str}' (string)"); return; case long l_val: System.Diagnostics.Debug.WriteLine($"{l_val} (long)"); return; case int i_val: System.Diagnostics.Debug.WriteLine($"{i_val} (int)"); return; case short s_val: System.Diagnostics.Debug.WriteLine($"{s_val} (short)"); return; case double d_val: System.Diagnostics.Debug.WriteLine($"{d_val} (double)"); return; case float f_val: System.Diagnostics.Debug.WriteLine($"{f_val} (float)"); return; case DateTime dt_val: System.Diagnostics.Debug.WriteLine($"{dt_val} (DateTime)"); return; case DateOnly dt_only_val: System.Diagnostics.Debug.WriteLine($"{dt_only_val} (DateOnly)"); return; case TimeOnly tm_only_val: System.Diagnostics.Debug.WriteLine($"{tm_only_val} (TimeOnly)"); return; case DateTimeOffset dt_tm_offset_val: System.Diagnostics.Debug.WriteLine( $"{dt_tm_offset_val} (DateTimeOffset)"); return; case System.Guid guid_val: var guid_string = guid_val.ToString("B"); System.Diagnostics.Debug.WriteLine($"'{guid_string}' (Guid)"); return; case Geometry geom_val: var geom_type = geom_val.GeometryType.ToString(); var is_empty = geom_val.IsEmpty; var wkid = geom_val.SpatialReference?.Wkid ?? 0; System.Diagnostics.Debug.WriteLine( $"geometry: {geom_type}, empty: {is_empty}, sr_wkid {wkid} (shape)"); return; default: //Blob? Others? var type_str = value.GetType().ToString(); System.Diagnostics.Debug.WriteLine($"Primitive: {type_str}"); return; } } // ...submit query or search //using (var kg_rc = kg.SubmitQuery(kg_qf)) { //using (var kg_rc = kg.SubmitSearch(kg_sf)) { // ...wait for rows ... // while (await kg_rc.WaitForRowsAsync()) { // ...rows have been retrieved // while (kg_rc.MoveNext()) { // ...get the current KnowledgeGraphRow // using (var graph_row = kg_rc.Current) { // var val_count = (int)graph_row.GetCount(); // for (int i = 0; i<val_count; i++) // ProcessKnowledgeGraphRowValue(graph_row[i]);
Target Platforms: Windows 11, Windows 10