架构优化
此页面中的所有示例都假设 |
虽然 Neo4j 不强制使用架构,但在写入数据之前添加索引和约束可以提高写入效率。在更新节点或关系时,存在约束也是避免重复的最佳方法。
架构优化选项总结如下。
此处描述的架构优化选项不能与 |
选项 | 描述 | 值 | 默认值 |
---|---|---|---|
|
使用 (已弃用,推荐使用 |
|
|
|
|
|
|
|
|
|
|
|
创建节点和关系上的 属性类型和属性存在 约束,强制执行 DataFrame 架构中的类型和非空性。 |
用逗号分隔的 |
|
节点属性上的索引
Neo4j 中的 索引 通常用于提高搜索性能。
您可以通过将 schema.optimization.type
选项设置为 INDEX
来创建索引。
val df = List(
"Product 1",
"Product 2",
).toDF("name")
df.write
.format("org.neo4j.spark.DataSource")
.mode(SaveMode.Overwrite)
.option("labels", ":Product")
.option("node.keys", "name")
.option("schema.optimization.type", "INDEX")
.save()
架构查询
在写入过程开始之前,连接器会运行以下架构查询
CREATE INDEX spark_INDEX_Product_name FOR (n:Product) ON (n.name)
索引名称的格式为 spark_INDEX_<LABEL>_<NODE_KEYS>
,其中 <LABEL>
是 labels
选项中的第一个标签,<NODE_KEYS>
是 node.keys
选项中指定的单个或多个属性的用连字符分隔的序列。
备注
-
如果索引已存在,则不会重新创建它。
-
对于多个标签,仅使用第一个标签来创建索引。
节点属性唯一性约束
节点属性唯一性约束 确保对所有具有特定标签的节点,属性值是唯一的。对于多个属性上的属性唯一性约束,属性值的组合是唯一的。
您可以通过将 schema.optimization.node.keys
选项设置为 UNIQUE
来创建约束。
val df = List(
"Product 1",
"Product 2",
).toDF("name")
df.write
.format("org.neo4j.spark.DataSource")
.mode(SaveMode.Overwrite)
.option("labels", ":Product")
.option("node.keys", "name")
.option("schema.optimization.node.keys", "UNIQUE")
.save()
架构查询
在写入过程开始之前,连接器会运行以下架构查询
CREATE CONSTRAINT `spark_NODE_UNIQUE-CONSTRAINT_Product_name` IF NOT EXISTS FOR (e:Product) REQUIRE (e.name) IS UNIQUE
备注
-
如果约束已存在,则不会重新创建它。
-
对于多个标签,仅使用第一个标签来创建索引。
-
如果对同一属性已存在键约束,则无法对节点属性创建唯一性约束。
-
此架构优化仅适用于
Overwrite
保存模式。
在 5.3.0 版之前,可以使用 |
节点键约束
节点键约束 确保,对于给定的节点标签和属性集
-
所有属性都存在于具有该标签的所有节点上。
-
属性值的组合是唯一的。
您可以通过将 schema.optimization.node.keys
选项设置为 KEY
来创建约束。
val df = List(
"Product 1",
"Product 2",
).toDF("name")
df.write
.format("org.neo4j.spark.DataSource")
.mode(SaveMode.Overwrite)
.option("labels", ":Product")
.option("node.keys", "name")
.option("schema.optimization.node.keys", "KEY")
.save()
架构查询
在写入过程开始之前,连接器会运行以下架构查询
CREATE CONSTRAINT `spark_NODE_KEY-CONSTRAINT_Product_name` IF NOT EXISTS FOR (e:Product) REQUIRE (e.name) IS NODE KEY
备注
-
如果约束已存在,则不会重新创建它。
-
如果对同一属性已存在唯一性约束,则无法对节点属性创建键约束。
-
此架构优化仅适用于
Overwrite
保存模式。
关系属性唯一性约束
关系属性唯一性约束 确保对所有具有特定类型的关系,属性值是唯一的。对于多个属性上的属性唯一性约束,属性值的组合是唯一的。
您可以通过将 schema.optimization.relationship.keys
选项设置为 UNIQUE
来创建约束。
val df = Seq(
("John", "Doe", 1, "Product 1", 200, "ABC100"),
("Jane", "Doe", 2, "Product 2", 100, "ABC200")
).toDF("name", "surname", "customerID", "product", "quantity", "order")
df.write
.mode(SaveMode.Overwrite)
.format("org.neo4j.spark.DataSource")
.option("relationship", "BOUGHT")
.option("relationship.save.strategy", "keys")
.option("relationship.source.save.mode", "Overwrite")
.option("relationship.source.labels", ":Customer")
.option("relationship.source.node.properties", "name,surname,customerID:id")
.option("relationship.source.node.keys", "customerID:id")
.option("relationship.target.save.mode", "Overwrite")
.option("relationship.target.labels", ":Product")
.option("relationship.target.node.properties", "product:name")
.option("relationship.target.node.keys", "product:name")
.option("relationship.properties", "quantity,order")
.option("schema.optimization.relationship.keys", "UNIQUE")
.option("relationship.keys", "order")
.save()
架构查询
在写入过程开始之前,连接器会运行以下架构查询
CREATE CONSTRAINT `spark_RELATIONSHIP_UNIQUE-CONSTRAINT_BOUGHT_order` IF NOT EXISTS FOR ()-[e:BOUGHT]->() REQUIRE (e.order) IS UNIQUE
备注
-
如果约束已存在,则不会重新创建它。
-
如果对同一属性已存在键约束,则无法对关系属性创建唯一性约束。
-
此架构优化仅适用于
Overwrite
保存模式。
关系键约束
关系键约束 确保,对于给定的关系类型和属性集
-
所有属性都存在于具有该类型的 所有关系上。
-
属性值的组合是唯一的。
您可以通过将 schema.optimization.relationship.keys
选项设置为 KEY
来创建约束。
val df = Seq(
("John", "Doe", 1, "Product 1", 200, "ABC100"),
("Jane", "Doe", 2, "Product 2", 100, "ABC200")
).toDF("name", "surname", "customerID", "product", "quantity", "order")
df.write
.mode(SaveMode.Overwrite)
.format("org.neo4j.spark.DataSource")
.option("relationship", "BOUGHT")
.option("relationship.save.strategy", "keys")
.option("relationship.source.save.mode", "Overwrite")
.option("relationship.source.labels", ":Customer")
.option("relationship.source.node.properties", "name,surname,customerID:id")
.option("relationship.source.node.keys", "customerID:id")
.option("relationship.target.save.mode", "Overwrite")
.option("relationship.target.labels", ":Product")
.option("relationship.target.node.properties", "product:name")
.option("relationship.target.node.keys", "product:name")
.option("relationship.properties", "quantity,order")
.option("schema.optimization.relationship.keys", "KEY")
.option("relationship.keys", "order")
.save()
架构查询
在写入过程开始之前,连接器会运行以下架构查询
CREATE CONSTRAINT `spark_RELATIONSHIP_KEY-CONSTRAINT_BOUGHT_order` IF NOT EXISTS FOR ()-[e:BOUGHT]->() REQUIRE (e.order) IS RELATIONSHIP KEY
备注
-
如果约束已存在,则不会重新创建它。
-
如果对同一属性已存在唯一性约束,则无法对关系属性创建键约束。
-
此架构优化仅适用于
Overwrite
保存模式。
属性类型和属性存在约束
连接器使用 DataFrame 架构来强制执行类型(使用 数据类型映射 中描述的映射)以及每一列的 nullable
标志来确定是否强制执行存在。
您可以创建
-
通过将
schema.optimization
选项设置为TYPE
来为节点和关系创建属性类型约束。 -
通过将
schema.optimization
选项设置为EXISTS
来为节点和关系创建属性存在约束。 -
通过将
schema.optimization
选项设置为TYPE,EXISTS
来同时创建两者。
备注
-
如果约束已存在,则不会重新创建它。
在节点上
df.write
.format("org.neo4j.spark.DataSource")
.mode(SaveMode.Overwrite)
.option("labels", ":Person")
.option("node.keys", "surname")
.option("schema.optimization", "TYPE,EXISTS")
.save()
架构查询
在写入过程开始之前,连接器会运行以下架构查询(对 DataFrame 中的每一列运行一个查询)
CREATE CONSTRAINT `spark_NODE-TYPE-CONSTRAINT-Person-name` IF NOT EXISTS FOR (e:Person) REQUIRE e.name IS :: STRING
CREATE CONSTRAINT `spark_NODE-TYPE-CONSTRAINT-Person-surname` IF NOT EXISTS FOR (e:Person) REQUIRE e.surname IS :: STRING
CREATE CONSTRAINT `spark_NODE-TYPE-CONSTRAINT-Person-age` IF NOT EXISTS FOR (e:Person) REQUIRE e.age IS :: INTEGER
如果 DataFrame 中的某一列不可为空,则连接器会运行额外的架构查询。例如,如果 age
列不可为空,则连接器会运行以下架构查询
CREATE CONSTRAINT `spark_NODE-NOT_NULL-CONSTRAINT-Person-age` IF NOT EXISTS FOR (e:Person) REQUIRE e.age IS NOT NULL
在关系上
val df = Seq(
("John", "Doe", 1, "Product 1", 200, "ABC100"),
("Jane", "Doe", 2, "Product 2", 100, "ABC200")
).toDF("name", "surname", "customerID", "product", "quantity", "order")
df.write
.mode(SaveMode.Overwrite)
.format("org.neo4j.spark.DataSource")
.option("relationship", "BOUGHT")
.option("relationship.save.strategy", "keys")
.option("relationship.source.save.mode", "Overwrite")
.option("relationship.source.labels", ":Customer")
.option("relationship.source.node.properties", "name,surname,customerID:id")
.option("relationship.source.node.keys", "customerID:id")
.option("relationship.target.save.mode", "Overwrite")
.option("relationship.target.labels", ":Product")
.option("relationship.target.node.properties", "product:name")
.option("relationship.target.node.keys", "product:name")
.option("relationship.properties", "quantity,order")
.option("schema.optimization", "TYPE,EXISTS")
.save()
架构查询
在写入过程开始之前,连接器会运行以下架构查询(源节点和目标节点属性的属性类型约束查询,然后对表示关系属性的 DataFrame 中的每一列运行一个属性类型约束查询)
CREATE CONSTRAINT `spark_NODE-TYPE-CONSTRAINT-Customer-name` IF NOT EXISTS FOR (e:Customer) REQUIRE e.name IS :: STRING
CREATE CONSTRAINT `spark_NODE-TYPE-CONSTRAINT-Customer-surname` IF NOT EXISTS FOR (e:Customer) REQUIRE e.surname IS :: STRING
CREATE CONSTRAINT `spark_NODE-TYPE-CONSTRAINT-Customer-id` IF NOT EXISTS FOR (e:Customer) REQUIRE e.id IS :: INTEGER
CREATE CONSTRAINT `spark_NODE-TYPE-CONSTRAINT-Product-name` IF NOT EXISTS FOR (e:Product) REQUIRE e.name IS :: STRING
CREATE CONSTRAINT `spark_RELATIONSHIP-TYPE-CONSTRAINT-BOUGHT-quantity` IF NOT EXISTS FOR ()-[e:BOUGHT]->() REQUIRE e.quantity IS :: INTEGER
CREATE CONSTRAINT `spark_RELATIONSHIP-TYPE-CONSTRAINT-BOUGHT-order` IF NOT EXISTS FOR ()-[e:BOUGHT]->() REQUIRE e.order IS :: STRING
如果 DataFrame 中的某一列不可为空,则连接器会运行额外的架构查询。例如,如果 experience
列不可为空,则连接器会运行以下架构查询
CREATE CONSTRAINT `spark_NODE-NOT_NULL-CONSTRAINT-Customer-id` IF NOT EXISTS FOR (e:Customer) REQUIRE e.id IS NOT NULL
CREATE CONSTRAINT `spark_RELATIONSHIP-NOT_NULL-CONSTRAINT-BOUGHT-quantity` IF NOT EXISTS FOR ()-[e:BOUGHT]->() REQUIRE e.quantity IS NOT NULL