如何将 Wikidata 导入 Neo4j

我们假设您已阅读安装指南并熟悉其操作步骤。如果您尚未阅读,请查看安装说明入门教程

在本指南中,我们将向您展示如何使用 Wikidata 查询服务将 Wikidata 导入 Neo4j。具体来说,本文将使用 SPARQL HTTP 端点查询 Wikidata 查询服务,以检索国家和大陆的信息。

图配置

在将 RDF 数据导入 Neo4j 之前,我们首先需要创建一个图配置,以指示 Neosemantics 如何存储数据。为此,我们需要使用一组参数调用 `n10s.graphconfig.init` 过程。与入门教程一样,我们将使用 n10s 中的映射过程,在将从 Wikidata 检索到的数据持久化到 Neo4j 数据库时,自动重命名数据中使用的词汇术语。

根据图配置的不同,Neosemantics 将以不同的方式处理多值属性(多值属性在像 Wikidata 这样的多语言数据集中很常见,其中我们发现同一属性在同一节点上针对每种可用语言有多个值:United Kingdom、Regno Unito、Royaume Uni 等)。默认情况下,Neosemantics 将假定属性是单值的,同一节点上同一属性的每个新值将覆盖前一个值,但在某些情况下,保留所有值可能更有意义。我们可以应用配置设置以将这些值的数组存储在 Neo4j 中。

CALL n10s.graphconfig.init({
  handleVocabUris: 'MAP', (1)
  handleMultival: 'ARRAY', (2)
  keepLangTag: true, (3)
  keepCustomDataTypes: true, (4)
  applyNeo4jNaming: true (5)
})
1 将 `handleVocabUris` 设置为 `MAP` 指示 neosemantics 在使用 `n10s.nsprefixes.add` 和 `n10s.mapping.add` 过程将模式元素添加到图时应用映射。
2 此设置确保将多个值作为数组存储在 Neo4j 中,在这种情况下,我们对元素的多语言 `rdf:label` 感兴趣。
3 保留语言标签意味着每个翻译的属性都将带有后缀,例如:`United Kingdom@en` 或 `Regno Unito@it`。
4 此设置确保任何自定义(用户定义的非 XML 模式)数据类型也以字符串形式存储在 Neo4j 中,后跟其数据类型 URI。
5 将 Neo4j 推荐的命名应用于图元素 - 关系类型全部大写,标签使用驼峰命名法等。

创建约束

正如我们在教程中所做的那样,我们需要确保 `Resource` 标签的节点上的 URI 属性具有唯一约束。

CREATE CONSTRAINT n10s_unique_uri FOR (r:Resource)
REQUIRE r.uri IS UNIQUE

构建 SPARQL 查询

为了将数据导入 Neo4j,我们首先需要编写一个查询来从 Wikidata 中检索三元组列表。我们将为此使用 SPARQL CONSTRUCT 和 SPARQL DESCRIBE。我们最终的 RDF 查询将以主语、谓语和宾语的三元组形式返回信息,这些三元组使用来自多个词汇表/模式的术语。事物的唯一标识符和词汇元素可能最初会令人困惑,因为它们都是数字代码,但幸运的是 Wikidata 查询服务带有自动完成功能,我们也可以在 Wikidata.org 上浏览三元组。

维基百科(主要供人类消费)链接到 Wikidata(用于程序化使用的结构化数据)。如果您导航到维基百科条目,您还会在左侧导航中看到一个**Wikidata 项目**链接。这也可以使用键盘快捷键打开:Mac 上的 `Ctrl+Option+G`。

英国维基百科条目为例,它在 Wikidata 上有一个`Q145` 的引用。Wikidata 条目显示了一个可读的表格,其中包含针对该项目存储的所有三元组,包括名称、每年人口和预期寿命。

我们可以尝试使用Wikidata 查询服务进行程序化访问,以使用 `DESCRIBE` SPARQL 查询返回元素的所有已知三元组。

describe wd:Q145

总共有超过 800,000 个三元组,所以我们应该更具体地说明我们特别感兴趣的数据。

在**声明**标题下,我们可以看到英国被列为**英联邦王国**、**岛国**以及最重要的是主权国家——`Q3624078`实例 (`wdt:P31`)。我们可以使用这个三元组模式(某个事物是主权国家的实例)来识别所有国家,并将它们绑定到一个 `?country` 变量。

SELECT *
WHERE {
  ?country wdt:P31 wd:Q3624078;
    rdfs:label ?countryLabel.
  BIND(LANG(?countryLabel) AS ?countryLabelLang)
}
LIMIT 10

此查询显示,查询返回的第一个主语 `wd:Q757` 具有多种语言的标签。

国家 国家标签 国家标签语言

wd:Q16

加拿大

bi

wd:Q16

加拿大

bm

wd:Q16

কানাডা

bn

wd:Q16

ཁ་ན་ཌ།

bo

wd:Q16

কানাডা

bpy

wd:Q16

加拿大

bs

wd:Q16

Канада

bxr

wd:Q16

加拿大

cbk-zam

wd:Q16

nā-dâi

cdo

wd:Q16

Канада

前面 `n10s.graphconfig.init` 调用中的配置设置组合将确保

  • 这些值在 Neo4j 中以字符串数组形式存储 (`handleMultival: 'ARRAY'`)。

  • 这些值将存储,并在字符串末尾附加语言 (`keepLangTag: true`)。

或者,将 `handleMultival` 设置为 `OVERWRITE` 将只保留一个值。这在希望将 Neo4j 中的属性值保持为原子(单值而不是数组)时很有用,但在这种情况下,我们需要在 SPARQL 查询中过滤语言以获取我们感兴趣的值。我们可以为此使用 SPARQL 中的过滤器语句。

filter(lang(?countryLabel) = "en")`

为了演示从谓词导入关系的能力,我们可以将大陆属性 (`wdt:P30`) 添加到查询中。此 RDF 属性将一个国家与其所属大陆关联起来。然后我们还添加一个属性,即该国家的人口 (`wdt:P1082`)。Wikidata 在不同时间点测量某些属性。人口就是其中之一。为简洁起见,我们将不解释 Wikidata 模型的复杂性,而只是在查询中添加过滤器,使其只返回 2010 年之后的人口统计数据,并限制每个标签的语言为英语、阿拉伯语、俄语和中文。有关更多详细信息,请查阅 Wikidata 的文档和示例。

这是更新后的查询

SELECT *
WHERE {
  ?country wdt:P31 wd:Q3624078 ;
    rdfs:label ?countryLabel .
    filter(lang(?countryLabel) IN ("en", "ar", "ru", "zh")) . (1)
  ?country wdt:P30 ?continent .
  ?continent rdfs:label ?continentLabel .
  filter(lang(?continentLabel) IN ("en", "ar", "ru", "zh")) . (1)
  ?country p:P1082 ?populationStatement .
  ?populationStatement ps:P1082 ?population;
    pq:P585 ?date .
  filter(?date > "2010-01-01"^^xsd:dateTime)  (2)
}
LIMIT 10
1 将标签的语言过滤为只包含 `en`、`ar`、`ru` 和 `zh`。
2 只包含 2010 年 1 月 1 日之后的人口统计数据。

然后,我们可以使用 `WHERE` 子句中的信息来构建准备好导入 Neo4j 的三元组。

构建三元组

我们已经看到 SPARQL SELECT 查询返回表格结果,但我们希望获得 RDF 数据。要指示 Wikidata 查询服务返回三元组,我们可以将查询的 `SELECT` 部分替换为 `CONSTRUCT` 子句。`CONSTRUCT` 部分定义了 `WHERE` 子句中检索到的数据应如何返回。因此,我们可以使用此部分来重命名某些术语,甚至根据需要重构信息。SPARQL CONSTRUCT 查询的输出是一个主语、谓语和宾语三元组流,它们共同表示一个 RDF 图。

PREFIX neo: <neo4j://voc#> (1)
CONSTRUCT { (2)
  ?country a neo:Country . (3)
  ?country neo:countryName ?countryLabel . (4)
  ?country neo:inContinent ?continent . (5)
  ?continent neo:continentName ?continentLabel . (6)
  ?country neo:hasPopulationCount [ neo:count ?population ; neo:onDate ?date ] . (7)
  ?population a neo:PopulationCount
}
WHERE {
   ?country wdt:P31 wd:Q3624078 ;
    rdfs:label ?countryLabel .
    filter(lang(?countryLabel) IN ("en", "ar", "br", "zh")) .
  ?country wdt:P30 ?continent .
  ?continent rdfs:label ?continentLabel .
  filter(lang(?continentLabel) IN ("en", "ar", "br", "zh")) .
  ?country p:P1082 ?populationStatement .
  ?populationStatement ps:P1082 ?population;
    pq:P585 ?date .
  filter(?date > "2010-01-01"^^xsd:dateTime)
}
LIMIT 10
1 此语句定义了一个 `neo4j://` 命名空间。我们将定义新术语(Country、continentName 等),因此我们必须在 RDF 中为其提供一个完全限定的名称。
2 查询的 `CONSTRUCT` 部分定义了我们想要的三元组。
3 我们将 `wd:Q3624078` 替换为 `neo:Country`。Neosemantics 会将此语句转换为国家节点上的 `:Country` 标签。
4 国家节点将具有 `countryName` 属性(而不是 `rdf:label`),其值为元素的标签。
5 国家将与所属大陆具有 `inContinent` 关系,替换 `p:P1082`。
6 大陆将具有与 `?continentLabel` 对应的 `continentName` 属性。
7 对于人口统计数据,创建一个三元组来表示与新节点的关系,该节点具有日期和计数属性。
主语 谓语 宾语

wd:Q16

rdf:type

<neo4j://voc#Country>

wd:Q16

<neo4j://voc#countryName>

加拿大

wd:Q16

<neo4j://voc#inContinent>

wd:Q49

wd:Q49

<neo4j://voc#continentName>

北美洲

b0

<neo4j://voc#count>

35702707

b0

<neo4j://voc#onDate>

2015年1月1日

wd:Q16

<neo4j://voc#hasPopulationCount>

b0

wd:Q16

<neo4j://voc#countryName>

加拿大

预览数据

要预览数据在 Neo4j 中的外观,我们可以使用 `n10s.rdf.preview.fetch` 过程。在入门指南中,我们使用了静态 URI,但我们可以通过向以下 URL 发送 GET 请求来程序化地查询 Wikidata 的 API:

https://query.wikidata.org/sparql?query=<RDF>

由于 URL 需要查询的编码版本,我们可以使用 APOC 的 `apoc.text.urlencode` 函数来编码上面的 SPARQL 查询。该端点还要求我们发送一个带有我们希望消费的内容类型的 `Accept` 标头,在本例中为 `Turtle`。

在继续之前,请务必安装 APOC 插件并重新启动 Neo4j。

如果我们使用 `n10s.rdf.stream.fetch` 过程运行查询,我们可以看到三元组列表以及一些额外的元数据,如数据类型和语言标签。

流式传输 RDF 三元组
WITH 'PREFIX neo: <neo4j://voc#> (1)
CONSTRUCT { (2)
  ?country a neo:Country . (3)
  ?country neo:countryName ?countryLabel . (4)
  ?country neo:inContinent ?continent . (5)
  ?continent neo:continentName ?continentLabel . (6)
  ?country neo:hasPopulationCount [ neo:population ?population ; neo:onDate ?date ] . (7)
  ?population a neo:PopulationCount
}
WHERE {
   ?country wdt:P31 wd:Q3624078 ;
    rdfs:label ?countryLabel .
    filter(lang(?countryLabel) IN ("en", "ar", "br", "zh")) .
  ?country wdt:P30 ?continent .
  ?continent rdfs:label ?continentLabel .
  filter(lang(?continentLabel) IN ("en", "ar", "br", "zh")) .
  ?country p:P1082 ?populationStatement .
  ?populationStatement ps:P1082 ?population;
    pq:P585 ?date .
  filter(?date > "2010-01-01"^^xsd:dateTime)
}
LIMIT 10' AS sparql


CALL n10s.rdf.stream.fetch(
  'https://query.wikidata.org/sparql?query='+ apoc.text.urlencode(sparql),
  'Turtle' ,
  { headerParams: { Accept: "application/x-turtle" } }
)
YIELD subject, predicate, object, isLiteral, literalType, literalLang
RETURN subject, predicate, object, isLiteral, literalType, literalLang
主语 谓语 宾语 isLiteral literalType literalLang

"http://www.wikidata.org/entity/Q712"

"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"

"neo4j://voc#Country"

false

null

null

"http://www.wikidata.org/entity/Q712"

"neo4j://voc#countryName"

"斐济"

true

"http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"

"ar"

"http://www.wikidata.org/entity/Q712"

"neo4j://voc#inContinent"

"http://www.wikidata.org/entity/Q538"

false

null

null

"http://www.wikidata.org/entity/Q538"

"neo4j://voc#continentName"

"大洋洲"

true

"http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"

"en"

"genid-de0f637b17754c479bbee6732f96f4b1-b0"

"neo4j://voc#population"

"867921.0"

true

"http://www.w3.org/2001/XMLSchema#decimal"

null

"genid-de0f637b17754c479bbee6732f96f4b1-b0"

"neo4j://voc#onDate"

"2011-01-01T00:00:00Z"

true

"http://www.w3.org/2001/XMLSchema#dateTime"

null

"http://www.wikidata.org/entity/Q712"

"neo4j://voc#hasPopulationCount"

"genid-de0f637b17754c479bbee6732f96f4b1-b0"

false

null

null

"genid-de0f637b17754c479bbee6732f96f4b1-b1"

"neo4j://voc#population"

"874742.0"

true

"http://www.w3.org/2001/XMLSchema#decimal"

null

"genid-de0f637b17754c479bbee6732f96f4b1-b1"

"neo4j://voc#onDate"

"2012-01-01T00:00:00Z"

true

"http://www.w3.org/2001/XMLSchema#dateTime"

null

"http://www.wikidata.org/entity/Q712"

"neo4j://voc#hasPopulationCount"

"genid-de0f637b17754c479bbee6732f96f4b1-b1"

false

null

null

"genid-de0f637b17754c479bbee6732f96f4b1-b2"

"neo4j://voc#population"

"881065.0"

true

"http://www.w3.org/2001/XMLSchema#decimal"

null

"genid-de0f637b17754c479bbee6732f96f4b1-b2"

"neo4j://voc#onDate"

"2013-01-01T00:00:00Z"

true

"http://www.w3.org/2001/XMLSchema#dateTime"

null

"http://www.wikidata.org/entity/Q712"

"neo4j://voc#hasPopulationCount"

"genid-de0f637b17754c479bbee6732f96f4b1-b2"

false

null

null

"genid-de0f637b17754c479bbee6732f96f4b1-b3"

"neo4j://voc#population"

"915303.0"

true

"http://www.w3.org/2001/XMLSchema#decimal"

null

"genid-de0f637b17754c479bbee6732f96f4b1-b3"

"neo4j://voc#onDate"

"2016-07-01T00:00:00Z"

true

"http://www.w3.org/2001/XMLSchema#dateTime"

null

"http://www.wikidata.org/entity/Q712"

"neo4j://voc#hasPopulationCount"

"genid-de0f637b17754c479bbee6732f96f4b1-b3"

false

null

null

"genid-de0f637b17754c479bbee6732f96f4b1-b4"

"neo4j://voc#population"

"905502.0"

true

"http://www.w3.org/2001/XMLSchema#decimal"

null

"genid-de0f637b17754c479bbee6732f96f4b1-b4"

"neo4j://voc#onDate"

"2017-01-01T00:00:00Z"

true

"http://www.w3.org/2001/XMLSchema#dateTime"

null

"http://www.wikidata.org/entity/Q712"

"neo4j://voc#hasPopulationCount"

"genid-de0f637b17754c479bbee6732f96f4b1-b4"

false

null

null

"http://www.wikidata.org/entity/Q712"

"neo4j://voc#countryName"

"斐济"

true

"http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"

"en"

`fetch` 方法在以下情况下非常有用:当我们想要在 neo4j 中预览 RDF 源(在本例中是 Wikidata 上的 SPARQL 查询)返回的三元组时,或者当我们想要使用 Cypher 处理它们而不是将导入委托给 neosemantics 时。

我们还可以在 Neo4j Browser 中使用 `n10s.rdf.preview.fetch` 过程,以图形形式预览数据。

将 RDF 预览为属性图
WITH 'PREFIX neo: <neo4j://voc#> (1)
CONSTRUCT { (2)
  ?country a neo:Country . (3)
  ?country neo:countryName ?countryLabel . (4)
  ?country neo:inContinent ?continent . (5)
  ?continent neo:continentName ?continentLabel . (6)
  ?country neo:hasPopulationCount [ neo:population ?population ; neo:onDate ?date ] . (7)
  ?population a neo:PopulationCount
}
WHERE {
   ?country wdt:P31 wd:Q3624078 ;
    rdfs:label ?countryLabel .
    filter(lang(?countryLabel) IN ("en", "ar", "br", "zh")) .
  ?country wdt:P30 ?continent .
  ?continent rdfs:label ?continentLabel .
  filter(lang(?continentLabel) IN ("en", "ar", "br", "zh")) .
  ?country p:P1082 ?populationStatement .
  ?populationStatement ps:P1082 ?population;
    pq:P585 ?date .
  filter(?date > "2010-01-01"^^xsd:dateTime)
}
LIMIT 10' AS sparql

CALL n10s.rdf.preview.fetch(
  'https://query.wikidata.org/sparql?query='+ apoc.text.urlencode(sparql),
  'Turtle' ,
  { headerParams: { Accept: "application/x-turtle" } }
)
YIELD nodes, relationships
RETURN nodes, relationships

该查询将返回一组通过查询的 `CONSTRUCT` 部分中定义的关系连接在一起的节点。

preview 1

您可以通过阅读 Wikidata 的数据访问页面了解更多访问 Wikidata 的信息。

修改输入

使用映射重命名图元素

由于 `applyNeo4jNaming` 配置选项设置为 `true`,Neosemantics 正在将关系类型转换为大写。在大多数情况下这都可以,但您可能更喜欢为模式元素创建特定的映射。

在上述预览中,将 `neo:inContinent` 模式元素转换为大写会产生一个不幸的副作用。与其使用 `INCONTINENT`,我们可以创建一个映射,在名称中添加下划线,使其更具可读性。

为此,我们首先需要创建对 RDF 查询的 `PREFIX` 部分中定义的模式和前缀的引用。

CALL n10s.nsprefixes.add('neo', 'neo4j://voc#')

创建模式引用后,我们可以从 `inContinent` 模式元素创建到 `IN_CONTINENT` 图元素的映射。

CALL n10s.mapping.add(
  'neo4j://voc#inContinent', (1)
  'IN_CONTINENT' (2)
)
1 应重命名的模式元素
2 将要创建的关系类型的名称

重新运行上面的 `n10s.rdf.preview.fetch` 过程,现在应该会显示不幸命名的关系现在更具可读性了。

preview 2

处理多值

如果我们查看查询返回的节点属性,所有内容目前都存储为数组。这是由于 `handleMultival` 选项设置为 `ARRAY`。

如果我们查看国家节点的属性,我们可以看到 `countryName` 存储为字符串数组。这很好,因为我们希望保留国家的国际名称。

国家属性
{
  "uri": "http://www.wikidata.org/entity/Q16",
  "countryName": [
    "Canada@en",
    "加拿大@zh"
  ]
}

但是,对于 Continent 节点,`onDate` 和 `population` 属性将始终只有一个值。

大陆属性
{
  "onDate": [
    "2016-01-01T00:00:00Z"
  ],
  "uri": "genid-0db1342360a44f0f987e27cecb9d4b0a-b8",
  "population": [
    36155487.0
  ]
}

将每个值存储在数组中会使查询变得复杂。相反,我们可以通过向 `multivalPropList` 提供一个属性键数组来指定哪些属性应存储为数组。一旦设置了此选项,任何未明确列出的属性都将被视为我们已将 `handleMultival` 设置为 `OVERWRITE`,将属性设置为最终值。

要更新图配置,您可以运行 `n10s.graphconfig.set`,提供一个更新的配置选项映射。此过程将使用提供的值覆盖当前配置,并返回所有配置选项的流。

CALL n10s.graphconfig.set({
  multivalPropList: ["neo4j://voc#countryName", "neo4j://voc#continentName"]
})

重新运行预览现在应该会显示 `population` 和 `onDate` 属性现在被视为单值。

更新的大陆属性
{
  "onDate": "2011-01-01T00:00:00Z",
  "uri": "genid-f540b5c1a72c45e591d7bf818f2bf57b-b5",
  "population": 33476688.0
}

但 `countryName` 属性仍保留一个值数组。

更新的国家
{
  "uri": "http://www.wikidata.org/entity/Q16",
  "countryName": [
    "Canada@en",
    "加拿大@zh"
  ]
}

持久化数据

对预览满意后,您可以运行具有相同参数的 `n10s.rdf.import.fetch` 过程。

WITH 'PREFIX neo: <neo4j://voc#>
CONSTRUCT {
  ?country a neo:Country .
  ?country neo:countryName ?countryLabel .
  ?country neo:inContinent ?continent .
  ?continent neo:continentName ?continentLabel .
  ?country neo:hasPopulationCount [ neo:population ?population ; neo:onDate ?date ] .
  ?population a neo:PopulationCount
}
WHERE {
   ?country wdt:P31 wd:Q3624078 ;
    rdfs:label ?countryLabel .
    filter(lang(?countryLabel) IN ("en", "ar", "br", "zh")) .
  ?country wdt:P30 ?continent .
  ?continent rdfs:label ?continentLabel .
  filter(lang(?continentLabel) IN ("en", "ar", "br", "zh")) .
  ?country p:P1082 ?populationStatement .
  ?populationStatement ps:P1082 ?population;
    pq:P585 ?date .
  filter(?date > "2010-01-01"^^xsd:dateTime)
}
' AS sparql

CALL n10s.rdf.import.fetch(
  'https://query.wikidata.org/sparql?query='+ apoc.text.urlencode(sparql),
  'Turtle' ,
  { headerParams: { Accept: "application/x-turtle" } }
)
YIELD terminationStatus, triplesLoaded, triplesParsed, namespaces, extraInfo
RETURN terminationStatus, triplesLoaded, triplesParsed, namespaces, extraInfo

取消限制应加载和解析超过 32,000 个三元组。

terminationStatus triplesLoaded triplesParsed namespaces extraInfo

"OK"

32210

32210

null

""

查看图内容

恭喜,您已将 Wikidata 中的数据持久化到图中。您现在可以使用下面的 Cypher 查询来查看您加载的内容。

MATCH (r:Resource)-[rel]-(x)
WHERE r.uri = 'http://www.wikidata.org/entity/Q46'
RETURN r,rel,x

处理多语言属性

我们提供的配置确保每个 `Country` 节点的 `countryName` 属性都是一个值数组,表示该国家特定语言的名称。如果我们查看该数组,每个项都是一个字符串,包含值、一个 `@` 符号,然后是语言。

{
  "uri": "http://www.wikidata.org/entity/Q902",
  "countryName": [
    "Bangladesh@en",
    "بنغلاديش@ar",
    "Bangladesh@br",
    "孟加拉国@zh"
  ]
}

Neosemantics 提供了许多帮助函数,用于从多语言数据中提取信息。

  • `n10s.rdf.getLangTag` - 给定一个字符串,从字符串末尾提取语言标签。

  • `n10s.rdf.getLangValue(language, values)` - 给定一个值或值数组,提取特定语言的值。

检索特定语言

要检索特定语言的值,您可以使用 `n10s.rdf.getLangValue` 函数。它接受两个参数:语言和值数组。如果值数组中存在表示该语言的字符串,则返回该值,否则函数将返回 `null`。

MATCH (c:Country)
RETURN c.countryName, n10s.rdf.getLangValue('en', c.countryName) AS englishName
ORDER BY c.countryName ASC
LIMIT 10
c.countryName englishName

["Albania@en", "ألبانيا@ar", "Albania@br", "阿尔巴尼亚@zh"]

"阿尔巴尼亚"

["Andorra@en", "أندورا@ar", "Andorra@br", "安道尔@zh"]

"安道尔"

["Angola@en", "安哥拉@zh", "أنغولا@ar", "Angola@br"]

"安哥拉"

["Antigua ha Barbuda@br", "أنتيغوا وباربودا@ar", "Antigua and Barbuda@en", "安提瓜和巴布达@zh"]

"安提瓜和巴布达"

["Armenia@en", "أرمينيا@ar", "亞美尼亞@zh", "Armenia@br"]

"亚美尼亚"

["Bahamas@br", "巴哈马@zh", "باهاماس@ar", "The Bahamas@en"]

"巴哈马"

["Bahrain@en", "البحرين@ar", "巴林@zh", "Bahrein@br"]

"巴林"

["Bangladesh@en", "بنغلاديش@ar", "Bangladesh@br", "孟加拉国@zh"]

"孟加拉国"

["Belarus@br", "Belarus@en", "白俄罗斯@zh", "روسيا البيضاء@ar"]

"白俄罗斯"

["Benin@br", "Benin@en", "贝宁@zh"]

"贝宁"

使用 APOC 创建映射

使用模式理解和 `n10s.rdf.getLangTag` 与 `n10s.rdf.getLangValue` 函数的组合,您可以提取一组 `[语言, 值]` 对。这可以传递给 `apoc.map.fromPairs` 以创建包含语言作为键和值作为值的映射。

MATCH (c:Country {uri: "http://www.wikidata.org/entity/Q145"})
RETURN apoc.map.fromPairs( (3)
  [ name IN c.countryName | (1)
    [ n10s.rdf.getLangTag(name),  n10s.rdf.getLangValue(n10s.rdf.getLangTag(name), name) ]  (2)
  ]
  ) AS countryNames
1 使用模式推导从 `countryName` 数组中提取一个临时 `name` 变量。
2 对于每个名称,返回一个包含语言标签(例如:`en`)和值(例如:`United Kingdom`)的对。
3 将该值传递给 `apoc.map.fromPairs` 函数,该函数将把这些对转换为一个映射。

这将返回以下输出

{
  "br": "Rouantelezh-Unanet",
  "en": "United Kingdom",
  "ar": "المملكة المتحدة",
  "zh": "英国"
}

结论

在本指南中,我们学习了如何

  • 使用 Wikidata 查询服务通过 RDF 查询检索数据,并将数据导入 Neo4j。

  • 更新 neosemantics 配置以将某些值存储为数组。

  • 使用 Neosemantics 辅助函数从数组中提取特定语言数据。

如果您在本教程中遇到任何问题,您可以在故障排除页面找到解决方案。

词汇表

Neo4j Browser

Neo4j Browser 是一个用于查询、可视化和数据交互的用户界面。如果您的数据库正在运行,通常可以通过 HTTP 在端口 `7474` 或通过 HTTPS 在端口 `7473` 访问,例如 https://:7474

APOC

APOC 是一个程序和函数库,旨在让您的 Neo4j 用户体验更轻松。

© . All rights reserved.