arcgis-knowledge-graphs
ArcGIS Knowledge Graphs
Use this skill for knowledge graphs, graph queries (openCypher), link chart visualization, and entity-relationship management.
Import Patterns
ESM (npm)
// Knowledge graph service
import * as knowledgeGraphService from "@arcgis/core/rest/knowledgeGraphService.js";
// Layers
import KnowledgeGraphLayer from "@arcgis/core/layers/KnowledgeGraphLayer.js";
import LinkChartLayer from "@arcgis/core/layers/LinkChartLayer.js";
// Views and charts
import WebLinkChart from "@arcgis/core/WebLinkChart.js";
import LinkChartView from "@arcgis/core/views/LinkChartView.js";
// Layout settings
import OrganicLayoutSettings from "@arcgis/core/linkChart/OrganicLayoutSettings.js";
import ChronologicalLayoutSettings from "@arcgis/core/linkChart/ChronologicalLayoutSettings.js";
import LinkChartLayoutSwitcher from "@arcgis/core/linkChart/LinkChartLayoutSwitcher.js";
CDN (dynamic import)
const knowledgeGraphService = await $arcgis.import(
"@arcgis/core/rest/knowledgeGraphService.js",
);
const KnowledgeGraphLayer = await $arcgis.import(
"@arcgis/core/layers/KnowledgeGraphLayer.js",
);
const WebLinkChart = await $arcgis.import("@arcgis/core/WebLinkChart.js");
const LinkChartView = await $arcgis.import(
"@arcgis/core/views/LinkChartView.js",
);
Knowledge Graph Service
Fetch Knowledge Graph
const url =
"https://your-server/server/rest/services/Hosted/YourKG/KnowledgeGraphServer";
const knowledgeGraph = await knowledgeGraphService.fetchKnowledgeGraph(url);
console.log("Graph name:", knowledgeGraph.name);
console.log("Entity types:", knowledgeGraph.dataModel.entityTypes);
console.log("Relationship types:", knowledgeGraph.dataModel.relationshipTypes);
Service Functions
| Function | Description |
|---|---|
fetchKnowledgeGraph(url) |
Fetch knowledge graph metadata and data model |
executeQuery(kg, params) |
Execute openCypher query, return all results |
executeQueryStreaming(kg, params) |
Stream large query results |
executeSearch(kg, params) |
Full-text search across entities |
executeApplyEdits(kg, params) |
Add, update, or delete entities and relationships |
KnowledgeGraphLayer
Add to Map
const kgLayer = new KnowledgeGraphLayer({
url: "https://your-server/server/rest/services/Hosted/YourKG/KnowledgeGraphServer",
});
await kgLayer.load();
map.add(kgLayer);
Configure Sublayers
const kgLayer = new KnowledgeGraphLayer({
url: "...",
inclusionModeDefinition: {
generateAllSublayers: false,
namedTypeDefinitions: new Map([
["Person", { useAllData: true }],
["Location", { useAllData: true }],
]),
},
});
Querying with openCypher
Basic Query
const result = await knowledgeGraphService.executeQuery(knowledgeGraph, {
openCypherQuery: "MATCH (n:Person) RETURN n LIMIT 10",
});
console.log("Results:", result.resultRows);
Streaming Query (Large Results)
const queryResults = await knowledgeGraphService.executeQueryStreaming(
knowledgeGraph,
{
openCypherQuery: "MATCH (n:Person)-[r]->(m) RETURN n, r, m",
},
);
const reader = queryResults.resultRowsStream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
value.forEach((row) => {
console.log("Row:", row);
});
}
Spatial Query with Bind Parameters
import Polygon from "@arcgis/core/geometry/Polygon.js";
const searchArea = new Polygon({
rings: [
[
[-76, 45],
[-70, 45],
[-70, 40],
[-76, 40],
[-76, 45],
],
],
});
const queryResults = await knowledgeGraphService.executeQueryStreaming(
knowledgeGraph,
{
openCypherQuery: `
MATCH path=(a:User)-[]->(b:Observation)
WHERE esri.graph.ST_Intersects($geometry, b.shape)
RETURN path
`,
bindParameters: {
geometry: searchArea,
},
},
);
Query with Filters
// Filter by property
const result = await knowledgeGraphService.executeQuery(knowledgeGraph, {
openCypherQuery: `
MATCH (p:Person)
WHERE p.age > 30 AND p.name CONTAINS 'John'
RETURN p
`,
});
// Query relationships
const result = await knowledgeGraphService.executeQuery(knowledgeGraph, {
openCypherQuery: `
MATCH (p:Person)-[r:WORKS_AT]->(c:Company)
WHERE c.name = 'Esri'
RETURN p.name, r.startDate, c.name
`,
});
Common openCypher Patterns
-- Find all entities of a type
MATCH (p:Person) RETURN p
-- Find relationships
MATCH (a)-[r]->(b) RETURN a, r, b
-- Find path with depth
MATCH path = (a:Person)-[:KNOWS*1..3]->(b:Person)
WHERE a.name = 'John'
RETURN path
-- Aggregate
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
RETURN c.name, COUNT(p) as employeeCount
-- Spatial filter
MATCH (loc:Location)
WHERE esri.graph.ST_Intersects($geometry, loc.shape)
RETURN loc
Search Knowledge Graph
const searchResults = await knowledgeGraphService.executeSearch(
knowledgeGraph,
{
searchQuery: "John Smith",
typeCategoryFilter: "entity", // "entity", "relationship", "both"
typeNames: ["Person", "Employee"],
returnSearchContext: true,
},
);
searchResults.results.forEach((result) => {
console.log("Found:", result.typeName, result.id);
console.log("Context:", result.searchContext);
});
Apply Edits
// Add entity
await knowledgeGraphService.executeApplyEdits(knowledgeGraph, {
entityAdds: [
{
typeName: "Person",
properties: { name: "Jane Doe", age: 28 },
},
],
});
// Update entity
await knowledgeGraphService.executeApplyEdits(knowledgeGraph, {
entityUpdates: [
{
typeName: "Person",
properties: { globalId: "{existing-global-id}", age: 29 },
},
],
});
// Delete entity
await knowledgeGraphService.executeApplyEdits(knowledgeGraph, {
entityDeletes: [
{
typeName: "Person",
ids: ["{global-id-to-delete}"],
},
],
});
// Add relationship
await knowledgeGraphService.executeApplyEdits(knowledgeGraph, {
relationshipAdds: [
{
typeName: "WORKS_AT",
properties: {
originGlobalId: "{person-global-id}",
destinationGlobalId: "{company-global-id}",
startDate: new Date(),
},
},
],
});
Data Model
const dataModel = knowledgeGraph.dataModel;
dataModel.entityTypes.forEach((entityType) => {
console.log("Entity:", entityType.name);
console.log("Properties:", entityType.properties);
});
dataModel.relationshipTypes.forEach((relType) => {
console.log("Relationship:", relType.name);
console.log("Origin:", relType.originEntityTypes);
console.log("Destination:", relType.destinationEntityTypes);
});
Link Chart Visualization
Create Link Chart (Core API)
const linkChartLayer = new LinkChartLayer({
url: "https://your-server/.../KnowledgeGraphServer",
});
const linkChart = new WebLinkChart({
layers: [linkChartLayer],
});
const linkChartView = new LinkChartView({
container: "linkChartDiv",
map: linkChart,
highlightOptions: {
color: [0, 255, 255, 1],
haloColor: [0, 255, 255, 0.5],
haloOpacity: 0.8,
},
});
Link Chart Component
<arcgis-link-chart>
<arcgis-legend slot="top-right"></arcgis-legend>
<arcgis-zoom slot="bottom-right"></arcgis-zoom>
</arcgis-link-chart>
<script type="module">
const linkChartComponent = document.querySelector("arcgis-link-chart");
await linkChartComponent.componentOnReady();
const lcView = linkChartComponent.view;
const linkChart = lcView.map;
await linkChart.addRecords([
{ id: "entity1", typeName: "Person" },
{ id: "entity2", typeName: "Company" },
]);
</script>
Adding and Removing Records
// Add records
await linkChart.addRecords([
{ id: "person-1", typeName: "Person" },
{ id: "company-1", typeName: "Company" },
{ id: "rel-1", typeName: "WORKS_AT" },
]);
// Remove records
await linkChart.removeRecords([{ id: "person-1", typeName: "Person" }]);
Expand Entities
await linkChart.expand({
ids: ["entity-id"],
typeName: "Person",
relationshipTypes: ["KNOWS", "WORKS_AT"],
direction: "both", // "outgoing", "incoming", "both"
});
Navigate to Entities
linkChartView.goTo([{ id: "person-1", typeName: "Person" }]);
Link Chart Events
linkChartView.on("click", async (event) => {
const response = await linkChartView.hitTest(event);
if (response.results.length > 0) {
const graphic = response.results[0].graphic;
console.log("Clicked:", graphic.attributes);
}
});
Update Link Chart from Query Results
async function updateLinkChart(queryResults, linkChart) {
const reader = queryResults.resultRowsStream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const records = [];
for (const row of value) {
for (const record of row[0].path) {
records.push({
id: record.id,
typeName: record.typeName,
});
}
}
await linkChart.addRecords(records);
}
}
Layout Settings
Organic Layout
const organicLayout = new OrganicLayoutSettings();
linkChart.layoutSettings = organicLayout;
Chronological Layout
const chronoLayout = new ChronologicalLayoutSettings();
linkChart.layoutSettings = chronoLayout;
Layout Switcher Widget
const layoutSwitcher = new LinkChartLayoutSwitcher({
view: linkChartView,
});
linkChartView.ui.add(layoutSwitcher, "top-right");
Layout Switcher Component
<arcgis-link-chart>
<arcgis-link-chart-layout-switcher
slot="top-right"
></arcgis-link-chart-layout-switcher>
</arcgis-link-chart>
WebLinkChart Properties
const webLinkChart = new WebLinkChart({
portalItem: { id: "LINKCHART_ID" },
layoutSettings: organicLayout,
});
// Save to portal
await webLinkChart.saveAs({
title: "My Link Chart",
snippet: "Visualization of entity relationships",
});
Common Pitfalls
-
Authentication required: Knowledge graph services typically require authentication — configure credentials or OAuth.
-
Streaming for large results: Use
executeQueryStreamingfor queries that may return many results;executeQueryloads everything into memory. -
Geometry conversion: Convert geometries to WGS84 before using in spatial queries with
esri.graph.ST_Intersects. -
Case sensitivity: openCypher property names are case-sensitive —
p.Nameandp.nameare different. -
Load before querying: Ensure
await kgLayer.load()before accessing sublayers or metadata. -
Link chart records: Both entities and relationships must be added as records for links to display.
Reference Samples
knowledgegraph-query— Querying knowledge graphs with openCypherknowledgegraph-knowledgegraphlayer— Using KnowledgeGraphLayerknowledgegraph-search— Full-text searchknowledgegraph-applyedits— Editing graph entitiesknowledgegraph-datamodelediting— Data model editinglinkchart— Link chart visualization
Related Skills
arcgis-layers— Layer configuration and managementarcgis-interaction— Hit testing and event handlingarcgis-editing— Feature editing patterns
More from saschabrunnerch/arcgis-maps-sdk-js-ai-context
arcgis-core-maps
Create 2D and 3D maps using ArcGIS Maps SDK for JavaScript. Use for initializing maps, scenes, views, and navigation. Supports both Map Components (web components) and Core API approaches.
60arcgis-widgets-ui
Build map user interfaces with ArcGIS widgets, Map Components, and Calcite Design System. Use for adding legends, layer lists, search, tables, time sliders, and custom UI layouts.
55arcgis-geometry-operations
Create, manipulate, and analyze geometries using geometry classes and geometry operators. Use for spatial calculations, geometry creation, buffering, intersections, unions, and mesh operations.
47arcgis-popup-templates
Configure rich popup content with text, fields, media, charts, attachments, and related records. Use when customizing feature popups, adding charts or images to popups, templating popup titles and field formatting, or displaying related record data on click.
45arcgis-imagery
Work with raster and imagery data using ImageryLayer, ImageryTileLayer, pixel filtering, raster functions, multidimensional data, and oriented imagery. Use for satellite imagery, elevation data, and scientific raster datasets.
42arcgis-authentication
Implement authentication with ArcGIS using OAuth 2.0, API keys, and identity management. Use for accessing secured services, portal items, and user-specific content.
40