Work with ArcGIS Knowledge graphs for storing and querying connected data. Use for graph databases, relationship visualization, and openCypher queries.
60
70%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./contexts/4.34/skills/arcgis-knowledge-graphs/SKILL.mdUse this skill for working with knowledge graphs, graph queries, and relationship visualization.
import KGModule from "@arcgis/core/rest/knowledgeGraphService.js";
const url = "https://your-server/server/rest/services/Hosted/YourKG/KnowledgeGraphServer";
const knowledgeGraph = await KGModule.fetchKnowledgeGraph(url);
console.log("Graph name:", knowledgeGraph.name);
console.log("Entity types:", knowledgeGraph.dataModel.entityTypes);
console.log("Relationship types:", knowledgeGraph.dataModel.relationshipTypes);import KnowledgeGraphLayer from "@arcgis/core/layers/KnowledgeGraphLayer.js";
const kgLayer = new KnowledgeGraphLayer({
url: "https://your-server/server/rest/services/Hosted/YourKG/KnowledgeGraphServer"
});
await kgLayer.load();
map.add(kgLayer);const kgLayer = new KnowledgeGraphLayer({
url: "...",
// Only include specific entity types
inclusionModeDefinition: {
generateAllSublayers: false,
namedTypeDefinitions: new Map([
["Person", { useAllData: true }],
["Location", { useAllData: true }]
])
}
});import KGModule from "@arcgis/core/rest/knowledgeGraphService.js";
const result = await KGModule.executeQuery(knowledgeGraph, {
openCypherQuery: "MATCH (n:Person) RETURN n LIMIT 10"
});
console.log("Results:", result.resultRows);const queryResults = await KGModule.executeQueryStreaming(knowledgeGraph, {
openCypherQuery: "MATCH (n:Person)-[r]->(m) RETURN n, r, m"
});
// Read stream
const reader = queryResults.resultRowsStream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
// Process chunk
value.forEach(row => {
console.log("Row:", row);
});
}import KGModule from "@arcgis/core/rest/knowledgeGraphService.js";
import Polygon from "@arcgis/core/geometry/Polygon.js";
// Create geometry for spatial filter
const searchArea = new Polygon({
rings: [[
[-76, 45],
[-70, 45],
[-70, 40],
[-76, 40],
[-76, 45]
]]
});
const queryResults = await KGModule.executeQueryStreaming(knowledgeGraph, {
openCypherQuery: `
MATCH path=(a:User)-[]->(b:Observation)
WHERE esri.graph.ST_Intersects($geometry, b.shape)
RETURN path
`,
bindParameters: {
geometry: searchArea
}
});// Filter by property
const result = await KGModule.executeQuery(knowledgeGraph, {
openCypherQuery: `
MATCH (p:Person)
WHERE p.age > 30 AND p.name CONTAINS 'John'
RETURN p
`
});
// Query relationships
const result = await KGModule.executeQuery(knowledgeGraph, {
openCypherQuery: `
MATCH (p:Person)-[r:WORKS_AT]->(c:Company)
WHERE c.name = 'Esri'
RETURN p.name, r.startDate, c.name
`
});import WebLinkChart from "@arcgis/core/WebLinkChart.js";
import LinkChartView from "@arcgis/core/views/LinkChartView.js";
import LinkChartLayer from "@arcgis/core/layers/LinkChartLayer.js";
const linkChartLayer = new LinkChartLayer({
url: "https://your-server/.../KnowledgeGraphServer"
});
const linkChart = new WebLinkChart({
layers: [linkChartLayer]
});
const linkChartView = new LinkChartView({
container: "linkChartDiv",
map: linkChart
});const linkChartView = new LinkChartView({
container: "linkChartDiv",
map: linkChart,
// Enable interaction
highlightOptions: {
color: [0, 255, 255, 1],
haloColor: [0, 255, 255, 0.5],
haloOpacity: 0.8
},
// Navigation
navigation: {
mouseWheelZoomEnabled: true,
browserTouchPanEnabled: true
}
});
// View 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);
}
});<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;
// Add records to link chart
linkChart.addRecords([
{ id: "entity1", typeName: "Person" },
{ id: "entity2", typeName: "Company" }
]);
</script>// Access layout settings
const layoutSettings = linkChart.layoutSettings;
// Set an OrganicLayoutSettings or ChronologicalLayoutSettings instance
linkChart.layoutSettings = organicLayout;import OrganicLayoutSettings from "@arcgis/core/linkCharts/OrganicLayoutSettings.js";
// Real properties include: absoluteIdealEdgeLength, autoRepulsionRadius,
// computationBudgetTime, among others. Refer to the API documentation
// for the full list of supported properties.
const organicLayout = new OrganicLayoutSettings();
linkChart.layoutSettings = organicLayout;import ChronologicalLayoutSettings from "@arcgis/core/linkCharts/ChronologicalLayoutSettings.js";
// Real properties include: durationLineWidth, timeBannerUTCOffsetInMinutes,
// among others. Refer to the API documentation for the full list of
// supported properties.
const chronoLayout = new ChronologicalLayoutSettings();
linkChart.layoutSettings = chronoLayout;import LinkChartLayoutSwitcher from "@arcgis/core/linkCharts/LinkChartLayoutSwitcher.js";
const layoutSwitcher = new LinkChartLayoutSwitcher({
view: linkChartView
});
linkChartView.ui.add(layoutSwitcher, "top-right");// 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" }
]);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
});
}
}
linkChart.addRecords(records);
}
}// Expand entity to show connections
await linkChart.expand({
ids: ["entity-id"],
typeName: "Person",
relationshipTypes: ["KNOWS", "WORKS_AT"],
direction: "both" // outgoing, incoming, both
});// Go to specific entities
linkChartView.goTo([
{ id: "person-1", typeName: "Person" }
]);import WebLinkChart from "@arcgis/core/WebLinkChart.js";
const webLinkChart = new WebLinkChart({
// Portal item (load existing)
portalItem: { id: "LINKCHART_ID" },
// Or create from scratch
layers: [linkChartLayer],
// Layout settings
layoutSettings: organicLayout
});
// Save to portal
await webLinkChart.saveAs({
title: "My Link Chart",
snippet: "Visualization of entity relationships"
});import KGModule from "@arcgis/core/rest/knowledgeGraphService.js";
const searchResults = await KGModule.executeSearch(knowledgeGraph, {
searchQuery: "John Smith",
typeCategoryFilter: "entity", // or "relationship", "both"
typeNames: ["Person", "Employee"],
returnSearchContext: true
});
searchResults.results.forEach(result => {
console.log("Found:", result.typeName, result.id);
console.log("Context:", result.searchContext);
});import KGModule from "@arcgis/core/rest/knowledgeGraphService.js";
// Add entity
const addResult = await KGModule.executeApplyEdits(knowledgeGraph, {
entityAdds: [{
typeName: "Person",
properties: {
name: "Jane Doe",
age: 28
}
}]
});
// Update entity
const updateResult = await KGModule.executeApplyEdits(knowledgeGraph, {
entityUpdates: [{
typeName: "Person",
properties: {
globalId: "{existing-global-id}",
age: 29
}
}]
});
// Delete entity
const deleteResult = await KGModule.executeApplyEdits(knowledgeGraph, {
entityDeletes: [{
typeName: "Person",
ids: ["{global-id-to-delete}"]
}]
});
// Add relationship
const relResult = await KGModule.executeApplyEdits(knowledgeGraph, {
relationshipAdds: [{
typeName: "WORKS_AT",
properties: {
originGlobalId: "{person-global-id}",
destinationGlobalId: "{company-global-id}",
startDate: new Date()
}
}]
});// Access data model
const dataModel = knowledgeGraph.dataModel;
// Entity types
dataModel.entityTypes.forEach(entityType => {
console.log("Entity:", entityType.name);
console.log("Properties:", entityType.properties);
});
// Relationship types
dataModel.relationshipTypes.forEach(relType => {
console.log("Relationship:", relType.name);
console.log("Origin:", relType.originEntityTypes);
console.log("Destination:", relType.destinationEntityTypes);
});-- Find all entities
MATCH (n) RETURN n
-- Find specific type
MATCH (p:Person) RETURN p
-- Find relationships
MATCH (a)-[r]->(b) RETURN a, r, b
-- Find path
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| Component | Purpose |
|---|---|
arcgis-link-chart-layout-switcher | Switch layout algorithms for link charts |
knowledgegraph-query - Querying knowledge graphsknowledgegraph-knowledgegraphlayer - Using KnowledgeGraphLayerknowledgegraph-search - Searching knowledge graph entitieslinkchart - Link chart visualization of graph dataAuthentication required: Knowledge graph services typically require authentication
Streaming for large results: Use executeQueryStreaming for queries that may return many results
Geometry conversion: Convert geometries to WGS84 before using in spatial queries
Case sensitivity: openCypher property names are case-sensitive
d84407b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.