如何将 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 查询服务进行程序化访问,以使用 `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 |
Gă |
nā-dâi |
cdo |
wd:Q16 |
Канада |
前面 `n10s.graphconfig.init` 调用中的配置设置组合将确保
-
这些值在 Neo4j 中以字符串数组形式存储 (`handleMultival: 'ARRAY'`)。
-
这些值将存储,并在字符串末尾附加语言 (`keepLangTag: true`)。
或者,将 `handleMultival` 设置为 `OVERWRITE` 将只保留一个值。这在希望将 Neo4j 中的属性值保持为原子(单值而不是数组)时很有用,但在这种情况下,我们需要在 SPARQL 查询中过滤语言以获取我们感兴趣的值。我们可以为此使用 SPARQL 中的过滤器语句。
|
为了演示从谓词导入关系的能力,我们可以将大陆属性 (`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` 过程运行查询,我们可以看到三元组列表以及一些额外的元数据,如数据类型和语言标签。
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` 过程,以图形形式预览数据。
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` 部分中定义的关系连接在一起的节点。
您可以通过阅读 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` 过程,现在应该会显示不幸命名的关系现在更具可读性了。
处理多值
如果我们查看查询返回的节点属性,所有内容目前都存储为数组。这是由于 `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 |
"" |
处理多语言属性
我们提供的配置确保每个 `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 用户体验更轻松。