| Exception | Description |
|---|---|
| ArcGIS.Core.CalledOnWrongThreadException | This method or property must be called within the lambda passed to QueuedTask.Run. |
{
await QueuedTask.Run(async () =>
{
//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)
bool includeProvenanceIfPresent = KnowledgeGraphSupportsProvenance(kg);
if (includeProvenanceIfPresent)
{
//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
});
}
{
await QueuedTask.Run(async () =>
{
//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
});
}
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 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 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 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 ArcGIS.Core.Geometry.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 kgRowCursor = kg.SubmitQuery(kg_qf)) { //using (var kgRowCursor = kg.SubmitSearch(kg_sf)) { // ...wait for rows ... // while (await kgRowCursor.WaitForRowsAsync()) { // ...rows have been retrieved // while (kgRowCursor.MoveNext()) { // ...get the current KnowledgeGraphRow // using (var graph_row = kgRowCursor.Current) { // var val_count = (int)graph_row.GetCount(); // for (int i = 0; i<val_count; i++) // ProcessKnowledgeGraphRowValue(graph_row[i]);
Target Platforms: Windows 11 Home, Pro, Enterprise (64 bit)