功能#
Cypher 变更日志格式#
[必需插件版本 | 4.9.0.1]
此扩展支持 多语言 变更日志(XML、SQL、YAML ...)。SQL 格式已别名为更具语义的 Cypher 格式。
Cypher 文件名必须以 .cypher
结尾。Cypher 变更日志必须以注释 --liquibase formatted cypher
开头。以下是一个受支持的 Cypher 文件示例
-- liquibase formatted cypher
-- changeset fbiville:my-movie-init
CREATE (:Movie {title: 'My Life', genre: 'Comedy'});
作为 文件夹包含 一部分的 Cypher 文件必须仅包含单个 Cypher 查询,且 **不包含** 注释指令。
Cypher 和回滚变更#
[必需插件版本 (Cypher 别名) | 4.7.1.1]
支持内置 SQL 和 回滚 变更。 SQL 变更也别名为 cypher
。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init" author="fbiville">
<neo4j:cypher>CREATE (:Movie {title: 'My Life', genre: 'Comedy'})</neo4j:cypher>
</changeSet>
<changeSet id="translate" author="fbiville">
<neo4j:cypher>MATCH (m:Movie {title: 'My Life'}) SET m.genre = 'Comédie'</neo4j:cypher>
<rollback>MATCH (m:Movie {title: 'My Life'}) SET m.genre = 'Comedy'</rollback>
</changeSet>
</databaseChangeLog>
警告
cypher
XML 标签需要以相应的扩展命名空间前缀开头。- 如果查询包含 XML 特殊字符(如
<
或>
),请确保在查询内容开头用<![CDATA[
和结尾用]]>
将其括起来。
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {title: 'My Life', genre: 'Comedy'})"
}
]
}
},
{
"changeSet": {
"id": "translate",
"author": "fbiville",
"changes": [
{
"cypher": "MATCH (m:Movie {title: 'My Life'}) SET m.genre = 'Comédie'"
}
],
"rollback": [
{
"cypher": "MATCH (m:Movie {title: 'My Life'}) SET m.genre = 'Comedy'"
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init
author: fbiville
changes:
- cypher: 'CREATE (:Movie {title: ''My Life'', genre: ''Comedy''})'
- changeSet:
id: translate
author: fbiville
changes:
- cypher: 'MATCH (m:Movie {title: ''My Life''}) SET m.genre = ''Comédie'''
rollback:
- cypher: 'MATCH (m:Movie {title: ''My Life''}) SET m.genre = ''Comedy'''
-- liquibase formatted cypher
-- changeset fbiville:my-movie-init
CREATE (:Movie {title: 'My Life', genre: 'Comedy'});
-- changeset fbiville:translate
MATCH (m:Movie {title: 'My Life'}) SET m.genre = 'Comédie'
-- rollback MATCH (m:Movie {title: 'My Life'}) SET m.genre = 'Comedy'
Neo4j 先决条件#
在 Liquibase 文档 中了解更多关于先决条件的信息,特别是 故障和错误处理部分。
内置先决条件支持#
从插件的第一个版本开始,此扩展已成功测试以下内置 先决条件
dbms
(以Neo4j
为目标)sqlCheck
(别名为cypherCheck
,见下文)
其他可能有效,但尚未经过测试。
版本检查#
[必需插件版本 | 4.9.0]
version
先决条件断言运行时 Neo4j 版本 **以** 指定字符串 **开头**。它可以与其他先决条件结合使用标准布尔运算符。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-neo4j-44-deployment" author="fbiville">
<preConditions onFail="CONTINUE">
<neo4j:version matches="4.4"/>
</preConditions>
<neo4j:cypher>CREATE (:Neo4j {neo4j44: true})</neo4j:cypher>
</changeSet>
<changeSet id="my-neo4j-non44-deployment" author="fbiville">
<preConditions onFail="CONTINUE">
<not>
<neo4j:version matches="4.4"/>
</not>
</preConditions>
<neo4j:cypher>CREATE (:Neo4j {neo4j44: false})</neo4j:cypher>
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-neo4j-44-deployment",
"author": "fbiville",
"preConditions": [
{
"onFail": "CONTINUE"
},
{
"version": {
"matches": "4.4"
}
}
],
"changes": [
{
"cypher": "CREATE (:Neo4j {neo4j44: true})"
}
]
}
},
{
"changeSet": {
"id": "my-neo4j-non44-deployment",
"author": "fbiville",
"preConditions": [
{
"onFail": "CONTINUE"
},
{
"not": {
"version": {
"matches": "4.4"
}
}
}
],
"changes": [
{
"cypher": "CREATE (:Neo4j {neo4j44: false})"
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-neo4j-44-deployment
author: fbiville
preConditions:
- onFail: 'CONTINUE'
- version:
matches: '4.4'
changes:
- cypher: 'CREATE (:Neo4j {neo4j44: true})'
- changeSet:
id: my-neo4j-non44-deployment
author: fbiville
preConditions:
- onFail: 'CONTINUE'
- not:
- version:
matches: '4.4'
changes:
- cypher: 'CREATE (:Neo4j {neo4j44: false})'
版本检查#
[必需插件版本 | 4.9.0]
edition
检查断言目标 Neo4j 部署是社区版还是企业版。它可以与其他先决条件结合使用标准布尔运算符。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-neo4j-ee-deployment" author="fbiville">
<preConditions onFail="CONTINUE">
<neo4j:edition enterprise="true"/>
</preConditions>
<neo4j:cypher>CREATE (:Neo4j {enterprise: true})</neo4j:cypher>
</changeSet>
<changeSet id="my-neo4j-ce-deployment" author="fbiville">
<preConditions onFail="CONTINUE">
<neo4j:edition enterprise="false"/>
</preConditions>
<neo4j:cypher>CREATE (:Neo4j {enterprise: false})</neo4j:cypher>
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-neo4j-ee-deployment",
"author": "fbiville",
"preConditions": [
{
"onFail": "CONTINUE"
},
{
"edition": {
"enterprise": true
}
}
],
"changes": [
{
"cypher": "CREATE (:Neo4j {enterprise: true})"
}
]
}
},
{
"changeSet": {
"id": "my-neo4j-ce-deployment",
"author": "fbiville",
"preConditions": [
{
"onFail": "CONTINUE"
},
{
"edition": {
"enterprise": false
}
}
],
"changes": [
{
"cypher": "CREATE (:Neo4j {enterprise: false})"
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-neo4j-ee-deployment
author: fbiville
preConditions:
- edition:
enterprise: true
- onFail: 'CONTINUE'
changes:
- cypher: 'CREATE (:Neo4j {enterprise: true})'
- changeSet:
id: my-neo4j-ce-deployment
author: fbiville
preConditions:
- edition:
enterprise: false
- onFail: 'CONTINUE'
changes:
- cypher: 'CREATE (:Neo4j {enterprise: false})'
Cypher 检查别名#
[必需插件版本 | 4.9.0]
cypherCheck
为现有的 sqlCheck
先决条件提供别名。目前,Cypher 格式的变更日志文件只能使用 sqlCheck
。cypherCheck
可以与其他先决条件结合使用标准布尔运算符。
警告
在 4.21.1.2 版本之前,JSON 和 YAML 变更日志必须指定 sql
属性而不是 cypher
。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-neo4j-deployment" author="fbiville">
<preConditions onFail="CONTINUE">
<neo4j:cypherCheck expectedResult="0">MATCH (n:Neo4j) RETURN count(n)</neo4j:cypherCheck>
</preConditions>
<neo4j:cypher>CREATE (:Neo4j)</neo4j:cypher>
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-neo4j-deployment",
"author": "fbiville",
"preConditions": [
{
"onFail": "CONTINUE"
},
{
"cypherCheck": {
"expectedResult": "0",
"cypher": "MATCH (n:Neo4j) RETURN count(n)"
}
}
],
"changes": [
{
"cypher": {
"cypher": "CREATE (:Neo4j)"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-neo4j-deployment
author: fbiville
preConditions:
- onFail: 'CONTINUE'
- cypherCheck:
expectedResult: '0'
cypher: MATCH (n:Neo4j) RETURN count(n)
changes:
- cypher:
cypher: CREATE (:Neo4j)
插入变更#
[必需插件版本 | 4.21.1]
此变更允许定义单个节点的创建,其中使用 labelName
指定单个标签。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
<changeSet id="insert-node" author="fbiville">
<neo4j:insert labelName="Person">
<column name="id" value="8987212b-a6ff-48a1-901f-8c4b39bd6d9e" type="uuid"/>
<column name="age" valueNumeric="30" type="integer"/>
<column name="first_name" value="Florent"/>
<column name="last_name" value="Biville"/>
<column name="local_date" valueDate="2022-12-25" type="date"/>
<column name="local_time" valueDate="22:23:24" type="date"/>
<column name="local_date_time" valueDate="2018-02-01T12:13:14" type="date"/>
<column name="zoned_date_time" valueDate="2020-07-12T22:23:24+02:00" type="date"/>
<column name="polite" valueBoolean="true" type="boolean"/>
<column name="picture" value="DLxmEfVUC9CAmjiNyVphWw==" type="blob"/>
<column name="bio"
value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean nisi tellus, elementum id mi vitae, faucibus lacinia purus. Integer nec velit sit amet velit tincidunt ultrices eu eu massa. Vestibulum in libero vel neque interdum blandit in non libero. Aenean iaculis, erat ac molestie laoreet, risus ex faucibus odio, a fermentum turpis elit eget ex. Donec volutpat bibendum enim pretium pulvinar. Proin rutrum neque dui, a suscipit tellus semper suscipit. Praesent lobortis ut lorem vitae volutpat. Pellentesque a lorem eu lacus faucibus facilisis nec sed metus. Aenean lacinia luctus ultricies. Pellentesque cursus justo non iaculis tristique. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Duis tempor nisi ut turpis bibendum facilisis. Donec aliquet porttitor lacus, non rhoncus lectus laoreet et."
type="clob"/>
</neo4j:insert>
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "insert-node",
"author": "fbiville",
"changes": [
{
"insert": {
"columns": [
{
"column": {
"name": "id",
"type": "uuid",
"value": "8987212b-a6ff-48a1-901f-8c4b39bd6d9e"
}
},
{
"column": {
"name": "age",
"type": "integer",
"valueNumeric": 30
}
},
{
"column": {
"name": "first_name",
"value": "Florent"
}
},
{
"column": {
"name": "last_name",
"value": "Biville"
}
},
{
"column": {
"name": "local_date",
"type": "date",
"valueDate": "2022-12-25"
}
},
{
"column": {
"name": "local_time",
"type": "date",
"valueDate": "22:23:24"
}
},
{
"column": {
"name": "local_date_time",
"type": "date",
"valueDate": "2018-02-01T12:13:14"
}
},
{
"column": {
"name": "zoned_date_time",
"type": "date",
"valueDate": "2020-07-12T22:23:24+02:00"
}
},
{
"column": {
"name": "polite",
"type": "boolean",
"valueBoolean": true
}
},
{
"column": {
"name": "picture",
"type": "blob",
"value": "DLxmEfVUC9CAmjiNyVphWw=="
}
},
{
"column": {
"name": "bio",
"type": "clob",
"value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean nisi tellus, elementum id mi vitae, faucibus lacinia purus. Integer nec velit sit amet velit tincidunt ultrices eu eu massa. Vestibulum in libero vel neque interdum blandit in non libero. Aenean iaculis, erat ac molestie laoreet, risus ex faucibus odio, a fermentum turpis elit eget ex. Donec volutpat bibendum enim pretium pulvinar. Proin rutrum neque dui, a suscipit tellus semper suscipit. Praesent lobortis ut lorem vitae volutpat. Pellentesque a lorem eu lacus faucibus facilisis nec sed metus. Aenean lacinia luctus ultricies. Pellentesque cursus justo non iaculis tristique. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Duis tempor nisi ut turpis bibendum facilisis. Donec aliquet porttitor lacus, non rhoncus lectus laoreet et."
}
}
],
"labelName": "Person"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: insert-node
author: fbiville
changes:
- insert:
columns:
- column:
name: id
type: uuid
value: 8987212b-a6ff-48a1-901f-8c4b39bd6d9e
- column:
name: age
type: integer
valueNumeric: !!float '30'
- column:
name: first_name
value: Florent
- column:
name: last_name
value: Biville
- column:
name: local_date
type: date
valueDate: '2022-12-25'
- column:
name: local_time
type: date
valueDate: '22:23:24'
- column:
name: local_date_time
type: date
valueDate: '2018-02-01T12:13:14'
- column:
name: zoned_date_time
type: date
valueDate: '2020-07-12T22:23:24+02:00'
- column:
name: polite
type: boolean
valueBoolean: true
- column:
name: picture
type: blob
value: DLxmEfVUC9CAmjiNyVphWw==
- column:
name: bio
type: clob
value: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
nisi tellus, elementum id mi vitae, faucibus lacinia purus. Integer
nec velit sit amet velit tincidunt ultrices eu eu massa. Vestibulum
in libero vel neque interdum blandit in non libero. Aenean iaculis,
erat ac molestie laoreet, risus ex faucibus odio, a fermentum turpis
elit eget ex. Donec volutpat bibendum enim pretium pulvinar. Proin rutrum
neque dui, a suscipit tellus semper suscipit. Praesent lobortis ut lorem
vitae volutpat. Pellentesque a lorem eu lacus faucibus facilisis nec
sed metus. Aenean lacinia luctus ultricies. Pellentesque cursus justo
non iaculis tristique. Vestibulum ante ipsum primis in faucibus orci
luctus et ultrices posuere cubilia curae; Duis tempor nisi ut turpis
bibendum facilisis. Donec aliquet porttitor lacus, non rhoncus lectus
laoreet et.
labelName: Person
有关每列支持的值类型的详细信息,请参阅 加载数据 文档。
加载数据#
[必需 Liquibase 核心版本 | 4.11.0] [必需插件版本 | 4.16.1.1]
假设以下 (S)CSV data.scsv
文件
name;age;some_date;ignored;uuid;is_polite;blob
Florent;30.5;2022-12-25;ignored;8d1208fc-f401-496c-9cb8-483fef121234;false;DLxmEfVUC9CAmjiNyVphWw==
Andrea;32;2020-07-12T22:23:24+02:00;ignored!;1bc59ddb-8d4d-41d0-9c9a-34e837de5678;true;NULL
Nathan;34;2018-02-01T12:13:14;ignored!;123e4567-e89b-12d3-a456-426614174000;true;NULL
Robert;36;22:23:24;ignored!;9986a49a-0cce-4982-b491-b8177fd0ef81;true;NULL
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="customer-import" author="asanturbano">
<loadData
file="e2e/load-data/data.scsv"
separator=";"
tableName="CsvPerson">
<column name="first_name" header="name" type="string"/>
<column name="wisdom_index" header="age" type="numeric"/>
<column name="some_date" index="2" type="date"/>
<column name="_" header="ignored" type="skip"/>
<column name="uuid" header="uuid" type="uuid"/>
<column name="polite" header="is_polite" type="boolean"/>
<column name="picture" header="blob" type="blob"/>
</loadData>
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "customer-import",
"author": "asanturbano",
"changes": [
{
"loadData": {
"columns": [
{
"column": {
"header": "name",
"name": "first_name",
"type": "string"
}
},
{
"column": {
"header": "age",
"name": "wisdom_index",
"type": "numeric"
}
},
{
"column": {
"index": 2,
"name": "some_date",
"type": "date"
}
},
{
"column": {
"header": "ignored",
"name": "_",
"type": "skip"
}
},
{
"column": {
"header": "uuid",
"name": "uuid",
"type": "uuid"
}
},
{
"column": {
"header": "is_polite",
"name": "polite",
"type": "boolean"
}
},
{
"column": {
"header": "blob",
"name": "picture",
"type": "blob"
}
}
],
"file": "e2e/load-data/data.scsv",
"separator": ";",
"tableName": "CsvPerson"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: customer-import
author: asanturbano
changes:
- loadData:
columns:
- column:
header: name
name: first_name
type: string
- column:
header: age
name: wisdom_index
type: numeric
- column:
index: 2
name: some_date
type: date
- column:
header: ignored
name: _
type: skip
- column:
header: uuid
name: uuid
type: uuid
- column:
header: is_polite
name: polite
type: boolean
- column:
header: blob
name: picture
type: blob
file: e2e/load-data/data.scsv
separator: ;
tableName: CsvPerson
此变更的常规文档位于 此处。
下表详细说明了每个支持的数据类型如何映射到其 Neo4j 对应项
加载数据类型 | Liquibase Java 类型 | 示例值 | 生成的 Neo4j Java 类型 |
---|---|---|---|
BLOB |
String |
DLxmEfVUC9CAmjiNyVphWw== (base64 编码) |
byte[] |
BOOLEAN |
Boolean |
true 或 false |
Boolean |
CLOB |
String |
String |
|
DATE |
java.sql.Timestamp |
2018-02-01T12:13:14 |
java.time.LocalDateTime |
DATE |
java.sql.Date |
2018-02-01 |
java.time.LocalDate |
DATE |
java.sql.Time |
12:13:14 |
java.time.LocalTime |
DATE |
liquibase.statement.DatabaseFunction |
2018-02-01T12:13:14+02:00 |
java.time.ZonedDateTime |
NUMERIC |
liquibase.change.ColumnConfig.ValueNumeric |
42 或 42.0 |
Long 或 Double |
STRING |
String |
"a string" |
String |
UUID |
String |
1bc59ddb-8d4d-41d0-9c9a-34e837de5678 |
String |
还支持 SKIP
:将忽略该值。
确保使用正确的 valueXxx
属性
valueBoolean
用于布尔值valueDate
用于日期/时间值valueNumeric
用于数值value
用于其他所有值
图重构#
节点合并#
[必需插件版本 | 4.13.0]
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher>CREATE (:Movie {title: 'My Life', genre: 'Comedy'})</neo4j:cypher>
<neo4j:cypher>CREATE (:Movie {title: 'My Life', genre: 'Horror'})</neo4j:cypher>
<neo4j:cypher>CREATE (:Movie {title: 'My Life', genre: 'Documentary'})</neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville">
<neo4j:mergeNodes fragment="(m:Movie {title: 'My Life'}) WITH m ORDER BY m.genre ASC" outputVariable="m">
<neo4j:propertyPolicy nameMatcher=".*" mergeStrategy="KEEP_FIRST"/>
</neo4j:mergeNodes>
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {title: 'My Life', genre: 'Comedy'})"
},
{
"cypher": "CREATE (:Movie {title: 'My Life', genre: 'Horror'})"
},
{
"cypher": "CREATE (:Movie {title: 'My Life', genre: 'Documentary'})"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"changes": [
{
"mergeNodes": {
"fragment": "(m:Movie {title: 'My Life'}) WITH m ORDER BY m.genre ASC",
"outputVariable": "m",
"propertyPolicies": [
{
"propertyPolicy": {
"mergeStrategy": "KEEP_FIRST",
"nameMatcher": ".*"
}
}
]
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {title: ''My Life'', genre: ''Comedy''})'
- cypher: 'CREATE (:Movie {title: ''My Life'', genre: ''Horror''})'
- cypher: 'CREATE (:Movie {title: ''My Life'', genre: ''Documentary''})'
- changeSet:
id: my-movie-init-fixed
author: fbiville
changes:
- mergeNodes:
fragment: '(m:Movie {title: ''My Life''}) WITH m ORDER BY m.genre ASC'
outputVariable: m
propertyPolicies:
- propertyPolicy:
mergeStrategy: 'KEEP_FIRST'
nameMatcher: .*
指定一个 Cypher 查询片段,该片段定义要匹配用于合并操作的节点。如果匹配的节点少于两个,则合并为空操作。
指定该片段中引用匹配节点的变量。这将被重复使用以创建要执行的内部合并 Cypher 查询。
最后,确保为每个持久化属性定义合并策略。此扩展将遍历每个唯一属性名称,按声明顺序选择第一个匹配的合并策略。如果至少有一个属性名称不匹配任何策略,则合并将失败并被取消。一旦为属性名称匹配到策略,将执行以下操作之一
KEEP_FIRST
:保留为该名称定义的第一个属性值KEEP_LAST
:保留为该名称定义的最后一个属性值KEEP_ALL
:将所有定义的属性值聚合到一个数组中(即使只找到一个值)
注意
"第一个" 和 "最后一个" 是由指定 Cypher 查询片段的排序定义的。强烈建议使用 ORDER BY
子句显式排序匹配的节点,如示例所示。
节点属性提取#
[必需插件版本 | 4.17.2]
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init" author="fbiville">
<neo4j:cypher>CREATE (:Movie {title: 'My Life', genre: 'Comedy'})</neo4j:cypher>
<neo4j:cypher>CREATE (:Movie {title: 'My Project', genre: 'Comedy'})</neo4j:cypher>
</changeSet>
<changeSet id="genre-extraction" author="marouane">
<neo4j:extractProperty property="genre" fromNodes="(m:Movie) WITH m ORDER BY id(m) ASC" nodesNamed="m">
<neo4j:toNodes withLabel="Genre" withProperty="genre">
<neo4j:linkedFromSource withType="HAS_GENRE" withDirection="OUTGOING" />
</neo4j:toNodes>
</neo4j:extractProperty>
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {title: 'My Life', genre: 'Comedy'})"
},
{
"cypher": "CREATE (:Movie {title: 'My Project', genre: 'Comedy'})"
}
]
}
},
{
"changeSet": {
"id": "genre-extraction",
"author": "marouane",
"changes": [
{
"extractProperty": {
"fromNodes": "(m:Movie) WITH m ORDER BY id(m) ASC",
"nodesNamed": "m",
"property": "genre",
"toNodes": {
"withLabel": "Genre",
"withProperty": "genre",
"linkedFromSource": {
"withDirection": "OUTGOING",
"withType": "HAS_GENRE"
}
}
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init
author: fbiville
changes:
- cypher: 'CREATE (:Movie {title: ''My Life'', genre: ''Comedy''})'
- cypher: 'CREATE (:Movie {title: ''My Project'', genre: ''Comedy''})'
- changeSet:
id: genre-extraction
author: marouane
changes:
- extractProperty:
fromNodes: '(m:Movie) WITH m ORDER BY id(m) ASC'
nodesNamed: 'm'
property: 'genre'
toNodes:
withLabel: 'Genre'
withProperty: 'genre'
linkedFromSource:
withDirection: 'OUTGOING'
withType: 'HAS_GENRE'
节点属性提取重构允许将节点属性提取到它们自己的节点中。与 节点合并重构 一样,要从中提取属性的节点作为 Cypher 片段(fromNodes
属性)和绑定到这些节点的变量名(nodesNamed
属性)指定。要提取的属性名称使用 property
属性指定。
由 Cypher 片段匹配的源节点将删除其属性。该属性将设置在提取的节点上,名称由 withProperty
属性描述。提取的节点的标签由 withLabel
属性定义。将 merge
属性设置为 true
以避免与可能存在的具有相同标签和属性的节点重复。默认行为是每次都创建提取的节点。
可以选择性地将提取的节点与源节点链接起来。在这种情况下,需要分别使用 withType
和 withDirection
属性指定类型和方向。
注意
关系方向是从源节点的角度来看的。在示例中,OUTGOING
意味着关系从源节点开始并指向提取的节点。相反,INCOMING
意味着关系从提取的节点进入源节点。
也可以通过将相应的 merge
属性设置为 true
来避免关系重复。默认情况下,始终创建关系。
警告
在节点上设置 merge=false
,而在关系上设置 merge=true
将触发验证警告。实际上,创建提取的节点意味着也将创建新的关系。在这种情况下,在关系上设置 merge=true
会导致不必要的执行开销。
节点标签重命名#
[必需插件版本 | 4.25.0.1]
标签重命名重构允许将一个标签重命名为另一个标签,匹配所有或部分节点,在单个事务或批处理中。
如下所示,重构的主要属性是
from
:现有标签的值to
:新标签的值,替换现有标签
全局重命名#
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher>CREATE (:Movie {title: 'My Life', genre: 'Comedy'})</neo4j:cypher>
<neo4j:cypher>CREATE (:Book {title: 'My Life', genre: 'Autobiography'})</neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville">
<neo4j:renameLabel from="Movie" to="Film" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {title: 'My Life', genre: 'Comedy'})"
},
{
"cypher": "CREATE (:Book {title: 'My Life', genre: 'Autobiography'})"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"changes": [
{
"renameLabel": {
"from": "Movie",
"to": "Film"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {title: ''My Life'', genre: ''Comedy''})'
- cypher: 'CREATE (:Book {title: ''My Life'', genre: ''Autobiography''})'
- changeSet:
id: my-movie-init-fixed
author: fbiville
changes:
- renameLabel:
from: 'Movie'
to: 'Film'
由于此操作可能会影响大量数据,因此在单个事务中运行此变更可能不可行,因为该事务可能会运行速度过慢,甚至内存不足。
为了防止这种情况,enableBatchImport
必须设置为 true
。由于它依赖于 CALL {} IN TRANSACTIONS
,因此封闭变更集的 runInTransaction
也必须设置为 false
。这会导致变更以批处理方式执行。
警告
此设置仅在目标 Neo4j 实例支持 CALL {} IN TRANSACTIONS
(版本 4.4 及更高版本)时才有效。否则,Neo4j 插件将在单个自动提交事务中运行更改。
请务必阅读有关 更改 runInTransaction
的后果。
batchSize
属性控制运行的事务数量。如果未设置该属性,则批次大小在 Neo4j 服务器端定义。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher>CREATE (:Movie {title: 'My Life', genre: 'Comedy'})</neo4j:cypher>
<neo4j:cypher>CREATE (:Book {title: 'My Life', genre: 'Autobiography'})</neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville" runInTransaction="false">
<neo4j:renameLabel from="Movie" to="Film" enableBatchImport="true" batchSize="1" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {title: 'My Life', genre: 'Comedy'})"
},
{
"cypher": "CREATE (:Book {title: 'My Life', genre: 'Autobiography'})"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"runInTransaction": false,
"changes": [
{
"renameLabel": {
"from": "Movie",
"to": "Film",
"enableBatchImport": true,
"batchSize": 1
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {title: ''My Life'', genre: ''Comedy''})'
- cypher: 'CREATE (:Book {title: ''My Life'', genre: ''Autobiography''})'
- changeSet:
id: my-movie-init-fixed
author: fbiville
runInTransaction: false
changes:
- renameLabel:
from: 'Movie'
to: 'Film'
enableBatchImport: true
batchSize: 1
部分重命名#
还可以设置以下属性,以便仅匹配具有 from
中指定标签的节点子集
fragment
指定与节点匹配的模式outputVariable
指定fragment
中定义的表示目标节点的 Cypher 变量名称
注意
要重命名的节点位于 fragment
中定义的内容与标签由 from
指定的节点的交集处。换句话说,如果 fragment
中定义的节点都不带有 from
中定义的标签,则重命名不会修改其中任何一个。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher>CREATE (:Movie {title: 'My Life', genre: 'Comedy'})</neo4j:cypher>
<neo4j:cypher>CREATE (:Movie {title: 'My Birthday', genre: 'Musical'})</neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville">
<neo4j:renameLabel from="Movie" to="Film" fragment="(m:Movie {title: 'My Birthday'})" outputVariable="m" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {title: 'My Life', genre: 'Comedy'})"
},
{
"cypher": "CREATE (:Movie {title: 'My Birthday', genre: 'Musical'})"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"changes": [
{
"renameLabel": {
"from": "Movie",
"to": "Film",
"fragment": "(m:Movie {title: 'My Birthday'})",
"outputVariable": "m"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {title: ''My Life'', genre: ''Comedy''})'
- cypher: 'CREATE (:Movie {title: ''My Birthday'', genre: ''Musical''})'
- changeSet:
id: my-movie-init-fixed
author: fbiville
changes:
- renameLabel:
from: 'Movie'
to: 'Film'
fragment: '(m:Movie {title: ''My Birthday''})'
outputVariable: 'm'
由于此操作可能会影响大量节点,因此在单个事务中运行更改可能不可行,因为该事务可能会运行速度过慢,甚至会耗尽内存。
由于此操作可能会影响大量数据,因此在单个事务中运行此变更可能不可行,因为该事务可能会运行速度过慢,甚至内存不足。
为了防止这种情况,enableBatchImport
必须设置为 true
。由于它依赖于 CALL {} IN TRANSACTIONS
,因此封闭变更集的 runInTransaction
也必须设置为 false
。这会导致变更以批处理方式执行。
警告
此设置仅在目标 Neo4j 实例支持 CALL {} IN TRANSACTIONS
(版本 4.4 及更高版本)时才有效。否则,Neo4j 插件将在单个自动提交事务中运行更改。
请务必阅读有关 更改 runInTransaction
的后果。
batchSize
属性控制运行的事务数量。如果未设置该属性,则批次大小在 Neo4j 服务器端定义。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher>CREATE (:Movie {title: 'My Life', genre: 'Comedy'})</neo4j:cypher>
<neo4j:cypher>CREATE (:Movie {title: 'My Birthday', genre: 'Musical'})</neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville" runInTransaction="false">
<neo4j:renameLabel from="Movie" to="Film" fragment="(m:Movie {title: 'My Birthday'})" outputVariable="m" enableBatchImport="true" batchSize="1" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {title: 'My Life', genre: 'Comedy'})"
},
{
"cypher": "CREATE (:Movie {title: 'My Birthday', genre: 'Musical'})"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"runInTransaction": false,
"changes": [
{
"renameLabel": {
"from": "Movie",
"to": "Film",
"fragment": "(m:Movie {title: 'My Birthday'})",
"outputVariable": "m",
"enableBatchImport": true,
"batchSize": 1
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {title: ''My Life'', genre: ''Comedy''})'
- cypher: 'CREATE (:Movie {title: ''My Birthday'', genre: ''Musical''})'
- changeSet:
id: my-movie-init-fixed
author: fbiville
runInTransaction: false
changes:
- renameLabel:
from: 'Movie'
to: 'Film'
fragment: '(m:Movie {title: ''My Birthday''})'
outputVariable: 'm'
enableBatchImport: true
batchSize: 1
关系类型重命名#
[必需插件版本 | 4.25.0.1]
类型重命名重构允许将一种类型重命名为另一种类型,匹配其所有或部分关系,在一个事务或批次中。
如下所示,重构的主要属性是
from
:现有类型的值to
:新类型的值,替换现有值
全局重命名#
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:SEEN_BY {date: 'now'}]->(:Person)]]></neo4j:cypher>
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:SEEN_BY {date: 'yesterday'}]->(:Dog)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville">
<neo4j:renameType from="SEEN_BY" to="VIEWED_BY" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie)-[:SEEN_BY {date: 'now'}]->(:Person)"
},
{
"cypher": "CREATE (:Movie)-[:SEEN_BY {date: 'yesterday'}]->(:Dog)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"changes": [
{
"renameType": {
"from": "SEEN_BY",
"to": "VIEWED_BY"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie)-[:SEEN_BY {date: ''now''}]->(:Person)'
- cypher: 'CREATE (:Movie)-[:SEEN_BY {date: ''yesterday''}]->(:Dog)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
changes:
- renameType:
from: 'SEEN_BY'
to: 'VIEWED_BY'
由于此操作可能会影响大量数据,因此在单个事务中运行此变更可能不可行,因为该事务可能会运行速度过慢,甚至内存不足。
为了防止这种情况,enableBatchImport
必须设置为 true
。由于它依赖于 CALL {} IN TRANSACTIONS
,因此封闭变更集的 runInTransaction
也必须设置为 false
。这会导致变更以批处理方式执行。
警告
此设置仅在目标 Neo4j 实例支持 CALL {} IN TRANSACTIONS
(版本 4.4 及更高版本)时才有效。否则,Neo4j 插件将在单个自动提交事务中运行更改。
请务必阅读有关 更改 runInTransaction
的后果。
batchSize
属性控制运行的事务数量。如果未设置该属性,则批次大小在 Neo4j 服务器端定义。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:SEEN_BY {date: 'now'}]->(:Person)]]></neo4j:cypher>
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:SEEN_BY {date: 'yesterday'}]->(:Dog)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville" runInTransaction="false">
<neo4j:renameType from="SEEN_BY" to="VIEWED_BY" enableBatchImport="true" batchSize="1" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie)-[:SEEN_BY {date: 'now'}]->(:Person)"
},
{
"cypher": "CREATE (:Movie)-[:SEEN_BY {date: 'yesterday'}]->(:Dog)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"runInTransaction": false,
"changes": [
{
"renameType": {
"from": "SEEN_BY",
"to": "VIEWED_BY",
"enableBatchImport": true,
"batchSize": 1
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie)-[:SEEN_BY {date: ''now''}]->(:Person)'
- cypher: 'CREATE (:Movie)-[:SEEN_BY {date: ''yesterday''}]->(:Dog)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
runInTransaction: false
changes:
- renameType:
from: 'SEEN_BY'
to: 'VIEWED_BY'
enableBatchImport: true
batchSize: 1
部分重命名#
还可以设置以下属性,以便仅匹配具有 from
中指定类型的关系子集
fragment
指定与关系匹配的模式outputVariable
指定fragment
中定义的表示目标关系的 Cypher 变量名称
注意
要重命名的关系位于 fragment
中定义的内容与类型由 from
指定的关系的交集处。换句话说,如果 fragment
中定义的关系都不具有 from
中定义的类型,则重命名不会修改其中任何一个。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:SEEN_BY {date: 'now'}]->(:Person)]]></neo4j:cypher>
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:SEEN_BY {date: 'yesterday'}]->(:Dog)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville">
<neo4j:renameType from="SEEN_BY" to="VIEWED_BY" fragment="(:Person)<-[r:SEEN_BY]-()" outputVariable="r" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie)-[:SEEN_BY {date: 'now'}]->(:Person)"
},
{
"cypher": "CREATE (:Movie)-[:SEEN_BY {date: 'yesterday'}]->(:Dog)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"changes": [
{
"renameType": {
"from": "SEEN_BY",
"to": "VIEWED_BY",
"fragment": "(:Person)<-[r:SEEN_BY]-()",
"outputVariable": "r"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie)-[:SEEN_BY {date: ''now''}]->(:Person)'
- cypher: 'CREATE (:Movie)-[:SEEN_BY {date: ''yesterday''}]->(:Dog)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
changes:
- renameType:
from: 'SEEN_BY'
to: 'VIEWED_BY'
fragment: '(:Person)<-[r:SEEN_BY]-()'
outputVariable: 'r'
由于此操作可能会影响大量数据,因此在单个事务中运行此变更可能不可行,因为该事务可能会运行速度过慢,甚至内存不足。
为了防止这种情况,enableBatchImport
必须设置为 true
。由于它依赖于 CALL {} IN TRANSACTIONS
,因此封闭变更集的 runInTransaction
也必须设置为 false
。这会导致变更以批处理方式执行。
警告
此设置仅在目标 Neo4j 实例支持 CALL {} IN TRANSACTIONS
(版本 4.4 及更高版本)时才有效。否则,Neo4j 插件将在单个自动提交事务中运行更改。
请务必阅读有关 更改 runInTransaction
的后果。
batchSize
属性控制运行的事务数量。如果未设置该属性,则批次大小在 Neo4j 服务器端定义。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:SEEN_BY {date: 'now'}]->(:Person)]]></neo4j:cypher>
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:SEEN_BY {date: 'yesterday'}]->(:Dog)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville" runInTransaction="false">
<neo4j:renameType from="SEEN_BY" to="VIEWED_BY" fragment="(:Person)<-[r:SEEN_BY]-()" outputVariable="r" enableBatchImport="true" batchSize="1" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie)-[:SEEN_BY {date: 'now'}]->(:Person)"
},
{
"cypher": "CREATE (:Movie)-[:SEEN_BY {date: 'yesterday'}]->(:Dog)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"runInTransaction": false,
"changes": [
{
"renameType": {
"from": "SEEN_BY",
"to": "VIEWED_BY",
"fragment": "(:Person)<-[r:SEEN_BY]-()",
"outputVariable": "r",
"enableBatchImport": true,
"batchSize": 1
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie)-[:SEEN_BY {date: ''now''}]->(:Person)'
- cypher: 'CREATE (:Movie)-[:SEEN_BY {date: ''yesterday''}]->(:Dog)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
runInTransaction: false
changes:
- renameType:
from: 'SEEN_BY'
to: 'VIEWED_BY'
fragment: '(:Person)<-[r:SEEN_BY]-()'
outputVariable: 'r'
enableBatchImport: true
batchSize: 1
关系方向反转#
[所需插件版本 | 4.25.1.1]
方向反转重构允许反转具有指定类型的关系的起点和终点节点,匹配其所有或部分关系,在一个事务或批次中。
如下所示,重构的主要属性是
type
:要反转的关系类型
全局反转#
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie)<-[:VIEWED_BY {date: 'now'}]-(:Person)]]></neo4j:cypher>
<neo4j:cypher><![CDATA[CREATE (:Movie)<-[:VIEWED_BY {date: 'yesterday'}]-(:Dog)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville">
<neo4j:invertDirection type="VIEWED_BY" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie)<-[:VIEWED_BY {date: 'now'}]-(:Person)"
},
{
"cypher": "CREATE (:Movie)<-[:VIEWED_BY {date: 'yesterday'}]-(:Dog)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"changes": [
{
"invertDirection": {
"type": "VIEWED_BY"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie)<-[:VIEWED_BY {date: ''now''}]-(:Person)'
- cypher: 'CREATE (:Movie)<-[:VIEWED_BY {date: ''yesterday''}]-(:Dog)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
changes:
- invertDirection:
type: 'VIEWED_BY'
由于此操作可能会影响大量数据,因此在单个事务中运行此变更可能不可行,因为该事务可能会运行速度过慢,甚至内存不足。
为了防止这种情况,enableBatchImport
必须设置为 true
。由于它依赖于 CALL {} IN TRANSACTIONS
,因此封闭变更集的 runInTransaction
也必须设置为 false
。这会导致变更以批处理方式执行。
警告
此设置仅在目标 Neo4j 实例支持 CALL {} IN TRANSACTIONS
(版本 4.4 及更高版本)时才有效。否则,Neo4j 插件将在单个自动提交事务中运行更改。
请务必阅读有关 更改 runInTransaction
的后果。
batchSize
属性控制运行的事务数量。如果未设置该属性,则批次大小在 Neo4j 服务器端定义。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie)<-[:VIEWED_BY {date: 'now'}]-(:Person)]]></neo4j:cypher>
<neo4j:cypher><![CDATA[CREATE (:Movie)<-[:VIEWED_BY {date: 'yesterday'}]-(:Dog)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville" runInTransaction="false">
<neo4j:invertDirection type="VIEWED_BY" enableBatchImport="true" batchSize="1" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie)<-[:VIEWED_BY {date: 'now'}]-(:Person)"
},
{
"cypher": "CREATE (:Movie)<-[:VIEWED_BY {date: 'yesterday'}]-(:Dog)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"runInTransaction": false,
"changes": [
{
"invertDirection": {
"type": "VIEWED_BY",
"enableBatchImport": true,
"batchSize": 1
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie)<-[:VIEWED_BY {date: ''now''}]-(:Person)'
- cypher: 'CREATE (:Movie)<-[:VIEWED_BY {date: ''yesterday''}]-(:Dog)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
runInTransaction: false
changes:
- invertDirection:
type: 'VIEWED_BY'
enableBatchImport: true
batchSize: 1
部分反转#
还可以设置以下属性,以便仅匹配具有 type
中指定类型的关系子集
fragment
指定与关系匹配的模式outputVariable
指定fragment
中定义的表示目标关系的 Cypher 变量名称
注意
要反转的关系位于 fragment
中定义的内容与类型由 type
指定的关系的交集处。换句话说,如果 fragment
中定义的关系都不具有 type
中定义的类型,则反转不会修改其中任何一个。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:VIEWED_BY {date: 'now'}]->(:Person)]]></neo4j:cypher>
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:VIEWED_BY {date: 'yesterday'}]->(:Dog)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville">
<neo4j:invertDirection type="VIEWED_BY" fragment="(:Person)-[r:VIEWED_BY]->()" outputVariable="r" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie)<-[:VIEWED_BY {date: 'now'}]-(:Person)"
},
{
"cypher": "CREATE (:Movie)-[:VIEWED_BY {date: 'yesterday'}]->(:Dog)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"changes": [
{
"invertDirection": {
"type": "VIEWED_BY",
"fragment": "(:Person)-[r:VIEWED_BY]->()",
"outputVariable": "r"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie)<-[:VIEWED_BY {date: ''now''}]-(:Person)'
- cypher: 'CREATE (:Movie)-[:VIEWED_BY {date: ''yesterday''}]->(:Dog)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
changes:
- invertDirection:
type: 'VIEWED_BY'
fragment: '(:Person)-[r:VIEWED_BY]->()'
outputVariable: 'r'
由于此操作可能会影响大量数据,因此在单个事务中运行此变更可能不可行,因为该事务可能会运行速度过慢,甚至内存不足。
为了防止这种情况,enableBatchImport
必须设置为 true
。由于它依赖于 CALL {} IN TRANSACTIONS
,因此封闭变更集的 runInTransaction
也必须设置为 false
。这会导致变更以批处理方式执行。
警告
此设置仅在目标 Neo4j 实例支持 CALL {} IN TRANSACTIONS
(版本 4.4 及更高版本)时才有效。否则,Neo4j 插件将在单个自动提交事务中运行更改。
请务必阅读有关 更改 runInTransaction
的后果。
batchSize
属性控制运行的事务数量。如果未设置该属性,则批次大小在 Neo4j 服务器端定义。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie)<-[:VIEWED_BY {date: 'now'}]-(:Person)]]></neo4j:cypher>
<neo4j:cypher><![CDATA[CREATE (:Movie)-[:VIEWED_BY {date: 'yesterday'}]->(:Dog)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville" runInTransaction="false">
<neo4j:invertDirection type="VIEWED_BY" fragment="(:Person)-[r:VIEWED_BY]->()" outputVariable="r" enableBatchImport="true" batchSize="1" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie)<-[:VIEWED_BY {date: 'now'}]-(:Person)"
},
{
"cypher": "CREATE (:Movie)-[:VIEWED_BY {date: 'yesterday'}]->(:Dog)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"runInTransaction": false,
"changes": [
{
"invertDirection": {
"type": "VIEWED_BY",
"fragment": "(:Person)-[r:VIEWED_BY]->()",
"outputVariable": "r",
"enableBatchImport": true,
"batchSize": 1
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie)<-[:VIEWED_BY {date: ''now''}]-(:Person)'
- cypher: 'CREATE (:Movie)-[:VIEWED_BY {date: ''yesterday''}]->(:Dog)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
runInTransaction: false
changes:
- invertDirection:
type: 'VIEWED_BY'
fragment: '(:Person)-[r:VIEWED_BY]->()'
outputVariable: 'r'
enableBatchImport: true
batchSize: 1
属性重命名#
[所需插件版本 | 4.25.1.1]
属性重命名重构允许重命名所有封闭实体的属性,或仅重命名节点或关系的属性。
如下所示,重构的主要属性是
from
:现有属性的名称to
:属性的新名称,替换现有名称entityType
:要匹配的封闭实体的类型。以下之一:ALL
(默认)、NODE
、RELATIONSHIP
。
全局重命名#
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville">
<neo4j:renameProperty from="calendar_date" to="date" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"changes": [
{
"renameProperty": {
"from": "calendar_date",
"to": "date"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {calendar_date: ''today''})-[:SEEN_BY {calendar_date: ''now''}]->(:Person)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
changes:
- renameProperty:
from: 'calendar_date'
to: 'date'
由于此操作可能会影响大量数据,因此在单个事务中运行此变更可能不可行,因为该事务可能会运行速度过慢,甚至内存不足。
为了防止这种情况,enableBatchImport
必须设置为 true
。由于它依赖于 CALL {} IN TRANSACTIONS
,因此封闭变更集的 runInTransaction
也必须设置为 false
。这会导致变更以批处理方式执行。
警告
此设置仅在目标 Neo4j 实例支持 CALL {} IN TRANSACTIONS
(版本 4.4 及更高版本)时才有效。否则,Neo4j 插件将在单个自动提交事务中运行更改。
请务必阅读有关 更改 runInTransaction
的后果。
batchSize
属性控制运行的事务数量。如果未设置该属性,则批次大小在 Neo4j 服务器端定义。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville" runInTransaction="false">
<neo4j:renameProperty from="calendar_date" to="date" enableBatchImport="true" batchSize="1" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"runInTransaction": false,
"changes": [
{
"renameProperty": {
"from": "calendar_date",
"to": "date",
"enableBatchImport": true,
"batchSize": 1
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {calendar_date: ''today''})-[:SEEN_BY {calendar_date: ''now''}]->(:Person)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
runInTransaction: false
changes:
- renameProperty:
from: 'calendar_date'
to: 'date'
enableBatchImport: true
batchSize: 1
仅节点属性重命名#
将 entityType
属性设置为 NODE
时,只会重命名节点的匹配属性
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville">
<neo4j:renameProperty from="calendar_date" to="date" entityType="NODE" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"changes": [
{
"renameProperty": {
"from": "calendar_date",
"to": "date",
"entityType": "NODE"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {calendar_date: ''today''})-[:SEEN_BY {calendar_date: ''now''}]->(:Person)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
changes:
- renameProperty:
from: 'calendar_date'
to: 'date'
entityType: 'NODE'
由于此操作可能会影响大量数据,因此在单个事务中运行此变更可能不可行,因为该事务可能会运行速度过慢,甚至内存不足。
为了防止这种情况,enableBatchImport
必须设置为 true
。由于它依赖于 CALL {} IN TRANSACTIONS
,因此封闭变更集的 runInTransaction
也必须设置为 false
。这会导致变更以批处理方式执行。
警告
此设置仅在目标 Neo4j 实例支持 CALL {} IN TRANSACTIONS
(版本 4.4 及更高版本)时才有效。否则,Neo4j 插件将在单个自动提交事务中运行更改。
请务必阅读有关 更改 runInTransaction
的后果。
batchSize
属性控制运行的事务数量。如果未设置该属性,则批次大小在 Neo4j 服务器端定义。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville" runInTransaction="false">
<neo4j:renameProperty from="calendar_date" to="date" entityType="NODE" enableBatchImport="true" batchSize="1" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"runInTransaction": false,
"changes": [
{
"renameProperty": {
"from": "calendar_date",
"to": "date",
"entityType": "NODE",
"enableBatchImport": true,
"batchSize": 1
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {calendar_date: ''today''})-[:SEEN_BY {calendar_date: ''now''}]->(:Person)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
runInTransaction: false
changes:
- renameProperty:
from: 'calendar_date'
to: 'date'
entityType: 'NODE'
enableBatchImport: true
batchSize: 1
仅关系属性重命名#
将 entityType
属性设置为 RELATIONSHIP
时,只会重命名关系的匹配属性
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville">
<neo4j:renameProperty from="calendar_date" to="date" entityType="RELATIONSHIP" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"changes": [
{
"renameProperty": {
"from": "calendar_date",
"to": "date",
"entityType": "RELATIONSHIP"
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {calendar_date: ''today''})-[:SEEN_BY {calendar_date: ''now''}]->(:Person)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
changes:
- renameProperty:
from: 'calendar_date'
to: 'date'
entityType: 'RELATIONSHIP'
由于此操作可能会影响大量数据,因此在单个事务中运行此变更可能不可行,因为该事务可能会运行速度过慢,甚至内存不足。
为了防止这种情况,enableBatchImport
必须设置为 true
。由于它依赖于 CALL {} IN TRANSACTIONS
,因此封闭变更集的 runInTransaction
也必须设置为 false
。这会导致变更以批处理方式执行。
警告
此设置仅在目标 Neo4j 实例支持 CALL {} IN TRANSACTIONS
(版本 4.4 及更高版本)时才有效。否则,Neo4j 插件将在单个自动提交事务中运行更改。
请务必阅读有关 更改 runInTransaction
的后果。
batchSize
属性控制运行的事务数量。如果未设置该属性,则批次大小在 Neo4j 服务器端定义。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:neo4j="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init-oops" author="fbiville">
<neo4j:cypher><![CDATA[CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)]]></neo4j:cypher>
</changeSet>
<changeSet id="my-movie-init-fixed" author="fbiville" runInTransaction="false">
<neo4j:renameProperty from="calendar_date" to="date" entityType="RELATIONSHIP" enableBatchImport="true" batchSize="1" />
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init-oops",
"author": "fbiville",
"changes": [
{
"cypher": "CREATE (:Movie {calendar_date: 'today'})-[:SEEN_BY {calendar_date: 'now'}]->(:Person)"
}
]
}
},
{
"changeSet": {
"id": "my-movie-init-fixed",
"author": "fbiville",
"runInTransaction": false,
"changes": [
{
"renameProperty": {
"from": "calendar_date",
"to": "date",
"entityType": "RELATIONSHIP",
"enableBatchImport": true,
"batchSize": 1
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init-oops
author: fbiville
changes:
- cypher: 'CREATE (:Movie {calendar_date: ''today''})-[:SEEN_BY {calendar_date: ''now''}]->(:Person)'
- changeSet:
id: my-movie-init-fixed
author: fbiville
runInTransaction: false
changes:
- renameProperty:
from: 'calendar_date'
to: 'date'
entityType: 'RELATIONSHIP'
enableBatchImport: true
batchSize: 1
更改集的 runInTransaction
#
runInTransaction
的默认值为 true
。这意味着给定更改集的所有更改都将在单个显式事务中运行。
这是正确的默认值,只有在需要以下两个 Cypher 结构中的任何一个时才应更改
- [自 Neo4j 4.4 起]
CALL {} IN TRANSACTIONS
- [直到 Neo4j 4.4]
PERIODIC COMMIT
实际上,在不禁用 runInTransaction
的情况下使用这些结构会导致类似的错误消息
A query with 'CALL { ... } IN TRANSACTIONS' can only be executed in an implicit transaction, but tried to execute in an explicit transaction.
在更改集上将 runInTransaction
设置为 false
意味着所有更改都将在其自己的自动提交(或隐式)事务中运行。
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="my-movie-init" author="fbiville" runInTransaction="false">
<sql>CALL { CREATE (:Movie {title: 'My Life', genre: 'Comedy'}) } IN TRANSACTIONS</sql>
</changeSet>
</databaseChangeLog>
{
"databaseChangeLog": [
{
"changeSet": {
"id": "my-movie-init",
"author": "fbiville",
"runInTransaction": false,
"changes": [
{
"cypher": "CALL { CREATE (:Movie {title: 'My Life', genre: 'Comedy'}) } IN TRANSACTIONS"
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: my-movie-init
author: fbiville
runInTransaction: false
changes:
- cypher: 'CALL { CREATE (:Movie {title: ''My Life'', genre: ''Comedy''}) } IN TRANSACTIONS'
-- liquibase formatted sql
-- changeset fbiville:my-movie-init runInTransaction:false
CALL { CREATE (:Movie {title: 'My Life', genre: 'Comedy'}) } IN TRANSACTIONS
历史一致性#
runInTransaction
是一款强大的工具,可能会导致意外后果。
如果封闭更改集的任何更改失败,则不会将更改集存储在历史图中。
重新运行此更改集会导致所有更改再次运行,即使之前已成功运行的更改也是如此。
在无法避免 runInTransactions="false"
的情况下,请确保受影响的更改集的查询是幂等的。定义 约束 并使用 Cypher 的 MERGE
而不是 CREATE
通常会有所帮助。
Neo4j 隔离级别速览#
CALL {} IN TRANSACTIONS
和 PERIODIC COMMIT
为每个批次生成一个新事务。由于 Neo4j 的默认隔离级别为“读已提交”,因此这些新事务可以读取之前事务修改的数据,无论这些事务源于同一个语句还是完全不同的语句。
让我们用一个简单的例子来说明这一点。
假设数据已使用以下方法初始化
CREATE (:Person {name: 'Alejandro'})
CREATE (:Person {name: 'Filipe'})
CREATE (:Person {name: 'Florent'})
CREATE (:Person {name: 'Marouane'})
CREATE (:Person {name: 'Nathan'})
Person
的节点,并具有 name
属性。
运行 MATCH (p:Person) CALL { WITH p DELETE p } IN TRANSACTIONS OF 2 ROWS
可能会有不同的结果。此查询以 2 行为一批删除所有具有 Person
标签的节点。
如果数据未被其他事务并发更改,则执行可能会成功并以 3 批运行。
如果并发事务创建更多 Person
节点,则可能需要更多批次。
如果并发事务删除 Person
节点,则可能需要更少的批次。
如果并发事务向上述任何节点创建关系,则 CALL {} IN TRANSACTIONS
也可能会失败,因为 DELETE
假设节点已断开连接(DETACH DELETE
删除节点及其关系)。