mcpField
A
arcgis-knowledge-graphs

arcgis-knowledge-graphs

github.com/saschabrunnerch数据与数据库2366 次安装29 周前更新
代码仓库

关于 arcgis-knowledge-graphs

arcgis-knowledge-graphs 是用于通过 JavaScript 操作 ArcGIS 知识图谱服务和链接图表的技能,面向使用 ArcGIS API 的开发者。内容涵盖图查询、搜索、编辑,以及实体关系可视化。

主要功能

  1. 01获取图谱元数据和数据模型
  2. 02执行或流式处理 openCypher 查询
  3. 03搜索图谱实体和关系
  4. 04添加、更新或删除图记录
  5. 05可视化并扩展链接图表

适用场景

  1. 01使用 openCypher 查询图谱数据
  2. 02流式处理大型查询结果
  3. 03编辑图谱实体与关系
  4. 04通过链接图表探索关联记录

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/saschabrunnerch/arcgis-maps-sdk-js-ai-context --skill arcgis-knowledge-graphs

安装后在 Claude Code 中输入/arcgis-knowledge-graphs确认已加载。

详细介绍

ArcGIS 知识图谱

此技能适用于知识图谱、图查询(openCypher)、关联图可视化以及实体关系管理。

导入模式

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(动态导入)
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",
);

知识图谱服务

获取知识图谱
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);
服务函数
函数描述
fetchKnowledgeGraph(url)获取知识图谱元数据和数据模型
executeQuery(kg, params)执行 openCypher 查询并返回所有结果
executeQueryStreaming(kg, params)流式传输大型查询结果
executeSearch(kg, params)对实体进行全文搜索
executeApplyEdits(kg, params)添加、更新或删除实体和关系

KnowledgeGraphLayer

添加到地图
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: "...",
  inclusionModeDefinition: {
    generateAllSublayers: false,
    namedTypeDefinitions: new Map([
      ["Person", { useAllData: true }],
      ["Location", { useAllData: true }],
    ]),
  },
});

使用 openCypher 查询

基本查询
const result = await knowledgeGraphService.executeQuery(knowledgeGraph, {
  openCypherQuery: "MATCH (n:Person) RETURN n LIMIT 10",
});

console.log("Results:", result.resultRows);
流式查询(大型结果集)
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);
  });
}
使用绑定参数进行空间查询
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,
    },
  },
);
使用过滤条件查询
// 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
  `,
});

常见 openCypher 模式

-- 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

搜索知识图谱

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);
});

应用编辑

// 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(),
      },
    },
  ],
});

数据模型

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);
});

关联图可视化

创建关联图(核心 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,
  },
});
关联图组件
<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>
添加和移除记录
// 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" }]);
展开实体
await linkChart.expand({
  ids: ["entity-id"],
  typeName: "Person",
  relationshipTypes: ["KNOWS", "WORKS_AT"],
  direction: "both", // "outgoing", "incoming", "both"
});
导航至实体
linkChartView.goTo([{ id: "person-1", typeName: "Person" }]);
关联图事件
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);
  }
});
根据查询结果更新关联图
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);
  }
}

布局设置

有机布局
const organicLayout = new OrganicLayoutSettings();
linkChart.layoutSettings = organicLayout;
时间顺序布局
const chronoLayout = new ChronologicalLayoutSettings();
linkChart.layoutSettings = chronoLayout;
布局切换器微件
const layoutSwitcher = new LinkChartLayoutSwitcher({
  view: linkChartView,
});

linkChartView.ui.add(layoutSwitcher, "top-right");
布局切换器组件
<arcgis-link-chart>
  <arcgis-link-chart-layout-switcher
    slot="top-right"
  ></arcgis-link-chart-layout-switcher>
</arcgis-link-chart>

WebLinkChart 属性

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",
});

常见问题

  1. 需要身份验证:知识图谱服务通常需要身份验证 — 请配置凭据或 OAuth。

  2. 大型结果集使用流式传输:对于可能返回大量结果的查询,请使用 executeQueryStreaming;executeQuery 会将所有内容加载到内存中。

  3. 几何转换:在空间查询中使用 esri.graph.ST_Intersects 之前,请将几何转换为 WGS84。

  4. 区分大小写:openCypher 属性名称区分大小写 — p.Name 和 p.name 是不同的。

  5. 查询前先加载:访问子图层或元数据之前,请确保已执行 await kgLayer.load()。

  6. 关联图记录:必须将实体和关系都添加为记录,才能显示链接。

参考示例

  • knowledgegraph-query — 使用 openCypher 查询知识图谱
  • knowledgegraph-knowledgegraphlayer — 使用 KnowledgeGraphLayer
  • knowledgegraph-search — 全文搜索
  • knowledgegraph-applyedits — 编辑图实体
  • knowledgegraph-datamodelediting — 数据模型编辑
  • linkchart — 关联图可视化

相关技能

  • arcgis-layers — 图层配置和管理
  • arcgis-interaction — 命中测试和事件处理
  • arcgis-editing — 要素编辑模式

评论

支持 Markdown