以编程方式使用文档

SAP HANA Cloud 知识图谱 是 SAP HANA Cloud 数据库中一个完全集成的知识图谱解决方案。

设置与安装

Prerequisites: - 启用三元组存储功能的 SAP HANA Cloud 实例 - See: 启用三元组存储

要使用 SAP HANA Knowledge Graph Engine 与 LangChain,请安装 @sap/hana-langchain 包及其对等依赖项:

npm install @sap/hana-langchain @langchain/core@latest langchain@latest
// Load environment variables if needed
dotenv.config();


const connectionParams = {
  host: process.env.HANA_DB_ADDRESS,
  port: process.env.HANA_DB_PORT,
  user: process.env.HANA_DB_USER,
  password: process.env.HANA_DB_PASSWORD,
};
const client = hanaClient.createConnection(connectionParams);

// connect to hanaDB
await new Promise<void>((resolve, reject) => {
  client.connect((err: Error) => {
    // Use arrow function here
    if (err) {
      reject(err);
    } else {
      console.log("Connected to SAP HANA successfully.");
      resolve();
    }
  });
});

然后,导入 HanaRdfGraph Class.

// const graph = new HanaRdfGraph({ connection: client, autoExtractOntology: true });

创建 HanaRdfGraph 实例

构造函数需要:

* **connection**:一个活动的 @sap/hana-client Connection 实例 * **graphUri**:命名图(或 "DEFAULT"),其中包含您的 RDF 数据 * **其中之一**: 1. **ontologyQuery**:用于提取模式三元组的 SPARQL CONSTRUCT 2. **ontologyUri**:托管本体图 URI 3. **ontologyLocalFile** + **ontologyLocalFileFormat**: a local Turtle/RDF file 4. **autoExtractOntology: true** (不推荐用于生产——见注释)

graphUri 与本体

* **graphUri**: SAP HANA Cloud 实例中包含实例数据的命名图(有时超过 100k+ 个三元组)。 If no graphUri, "" or "DEFAULT" 提供后,将使用默认图。 * **本体**:一个精简的模式(通常约 50-100 个三元组),描述类、属性、域、范围、标签、注释和子类关系。本体指导 SPARQL 生成和结果解释。

创建具有 **DEFAULT** 图的图实例

有关 DEFAULT 图的更多信息,请访问 DEFAULT 图和命名图.

const graphOptions = {
    connection: client,
    autoExtractOntology: true
};
const graph = new HanaRdfGraph(graphOptions);

// need to initialize once an instance is created.
await graph.initialize(graphOptions);

// const graphOptions = {
//     connection: client,
//     graphUri: "DEFAULT",
//     autoExtractOntology: true
// };

// const graph = new HanaRdfGraph(graphOptions);
// await graph.initialize(graphOptions);

// const graphOptions = {
//     connection: client,
//     graphUri: "",
//     autoExtractOntology: true
// };

// const graph = new HanaRdfGraph(graphOptions);
// await graph.initialize(graphOptions);

使用 graph_uri

const graphOptions = {
  connection: client,
  graphUri: "http://example.org/movies",
  autoExtractOntology: true,
};
const graph = new HanaRdfGraph(graphOptions);
await graph.initialize(graphOptions);

使用远程 ontology_uri

const graphOptions = {
    connection: client,
    ontologyUri: "<your_ontology_graph_uri>"
};
const graph = new HanaRdfGraph(graphOptions);
await graph.initialize(graphOptions);

使用自定义 ontology_query

使用自定义 CONSTRUCT 查询以有选择性地提取模式三元组。

const ontologyQuery = `
  PPREFIX owl: <http://www.w3.org/2002/07/owl#>
  PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
  PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
  PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
  CONSTRUCT {?cls rdf:type owl:Class . ?cls rdfs:label ?clsLabel . ?rel rdf:type ?propertyType . ?rel rdfs:label ?relLabel . ?rel rdfs:domain ?domain . ?rel rdfs:range ?range .}
  FROM <kgdocu_movies>
  WHERE { # get properties
    {SELECT DISTINCT ?domain ?rel ?relLabel ?propertyType ?range
      WHERE {
        ?subj ?rel ?obj .
        ?subj a ?domain .
        OPTIONAL{?obj a ?rangeClass .}
        FILTER(?rel != rdf:type)
        BIND(IF(isIRI(?obj) = true, owl:ObjectProperty, owl:DatatypeProperty) AS ?propertyType)
        BIND(COALESCE(?rangeClass, DATATYPE(?obj)) AS ?range)
        BIND(STR(?rel) AS ?uriStr)       # Convert URI to string
        BIND(REPLACE(?uriStr, "^.*[/#]", "") AS ?relLabel)
      }}
      UNION { # get classes
        SELECT DISTINCT ?cls ?clsLabel
        WHERE {
            ?instance a/rdfs:subClassOf* ?cls .
            FILTER (isIRI(?cls)) .
            BIND(STR(?cls) AS ?uriStr)       # Convert URI to string
            BIND(REPLACE(?uriStr, "^.*[/#]", "") AS ?clsLabel)
        }
      }
   }
`;

// can provide the graph_uri param as well if needed
const graphOptions = {
    connection: client,
    ontologyQuery
};
const graph = new HanaRdfGraph(graphOptions);
await graph.initialize(graphOptions);

从本地 RDF 文件加载本体

支持的 RDF 格式: Turtle, N-Triples, Notation-3, Trig, N-Quads.

const graphOptions = {
  connection: client,
  ontologyLocalFile: "<your_ontology_file_path>", // e.g., "ontology.ttl"
  ontologyLocalFileFormat: "<your_ontology_file_format>", // e.g., "Turtle", "N-Triples", "Notation-3", "Trig", "N-Quads"
};
const graph = new HanaRdfGraph(graphOptions);
await graph.initialize(graphOptions);

本体自动提取

(auto_extract_ontology=True):直接从实例数据推断模式信息。

const graphOptions = {
  connection: client,
  graphUri: "<your_graph_uri>",
  autoExtractOntology: true,
};
const graph = new HanaRdfGraph(graphOptions);
await graph.initialize(graphOptions);

> **注意**:自动提取是 **不** 推荐用于生产——它省略了重要的三元组,如 rdfs:label, rdfs:commentrdfs:subClassOf 总体而言。

执行 SPARQL 查询

您可以使用 query() 方法执行任意 SPARQL 查询(SELECT, ASK, CONSTRUCT等)对数据图执行。

该函数具有以下参数

  • * **查询**:SPARQL 查询字符串。
  • * **内容_类型**:输出的响应格式(默认为CSV)

请使用以下字符串来指定相应的格式。

  • * CSV: "sparql-results+xml"
  • * JSON: "sparql-results+json"
  • * XML: "sparql-results+csv"
  • * TSV: "sparql-results+tsv"

> **注意**:CONSTRUCT和ASK查询返回 turtleboolean 格式。

让我们向 Puppets graph.

await new Promise<void>((resolve, reject) => {
  const sparqlQuery = `CALL SYS.SPARQL_EXECUTE(?, ?, ?, ?)`;
  client.prepare(sparqlQuery, (err: Error, stmt) => {
    if (err) {
      reject(err);
    } else {
      const query = `
      INSERT DATA {
        GRAPH  {
             a ; <name> "Ernie"; <show> "Sesame Street".
             a ; <name> "Bert"; <show> "Sesame Street" .
            }
        }`;
      const params: HanaParameterList = {
        REQUEST: query,
        PARAMETER: "",
      };
      stmt?.exec(params, (err: Error) => {
        if (err) {
          reject(err);
        } else {
          resolve(stmt.getParameterValue(2));
        }
      });
    }
  });
});

然后,我们为 Puppets graph.

const graphOptions = {
  connection: client,
  graphUri: "Puppets",
  autoExtractOntology: true,
};

// create a Graph instance from a source URI
const graph = new HanaRdfGraph(graphOptions);

// need to initialize once an instance is created.
await graph.initialize(graphOptions);

给定的查询列出了 Puppets graph.

const results = await graph.query(`
SELECT ?s ?p ?o
WHERE {
    GRAPH  {
        ?s ?p ?o .
    }
}
ORDER BY ?s`);
console.log(results);
s,p,o
P1,name,Ernie
P1,show,Sesame Street
P1,http://www.w3.org/1999/02/22-rdf-syntax-ns#type,Puppet
P2,name,Bert
P2,show,Sesame Street
P2,http://www.w3.org/1999/02/22-rdf-syntax-ns#type,Puppet