Neo4j:不知道如何将图形映射到 Spring 数据 bean
Neo4j: Don't know how to map graph to Spring Data bean
我正在编写一个应用程序来捕获其他应用程序的配置属性。 Config
是我的主域对象。 Config
对象之间存在层次关系(一个 Config
[:OVERRIDES] 另一个 Config
)。因此,给定一个最底层的 Config
,我需要沿着层次结构一直向上到达最顶层的 Config
,并沿途收集 Config
对象的所有属性,将它们合并为一个最终 Config
。但是我不知道如何使用 Spring 数据来做到这一点。
这是 2 个 Config
对象的架构:
CREATE (c1:Config {name:'ConfigParent'});
SET c2.docker_tag='1.0.0';
SET c2.mem_limit='1gb';
MATCH (c1:Config {name: 'ConfigParent'})
CREATE (c2:Config {name:'ConfigChild'})-[:OVERRIDES]->(c1)
SET c2.docker_tag='1.0.1';
ConfigChild
属性需要与 ConfigParent
合并,ConfigParent
中的任何重复属性都将被覆盖。所以我最后的一组属性应该是:
name='ConfigMerged' //I don't know what this name would be?
docker_tag='1.0.1'
mem_limit='1gb'
Config
中可以有任何 key/value 对,因此不能按名称 return 编辑它们。我已经有了这个 CQL,我认为它可以满足我的要求:
MATCH p = SHORTESTPATH((c2:Config)<-[:OVERRIDES*]-(c1:Config))
WHERE c1.name = 'ConfigChild' and not (c2)-[:OVERRIDES]->()
UNWIND NODES(p) as props return PROPERTIES(props);
JSON 响应如下所示:
[
{
"keys": [
"properties(props)"
],
"length": 1,
"_fields": [
{
"name": "ConfigParent",
"docker_tag": "1.0.0",
"mem_limit": "1gb"
}
],
"_fieldLookup": {
"properties(props)": 0
}
},
{
"keys": [
"properties(props)"
],
"length": 1,
"_fields": [
{
"name": "ConfigChild",
"docker_tag": "1.0.1"
}
],
"_fieldLookup": {
"properties(props)": 0
}
}
]
问题是,我不知道如何将其映射到 POJO。我需要 Config
域对象还是 Properties
域对象?这是实现我目标的最佳 CQL 吗?
更新:我为 Config
提出了带注释的 POJO。但是当我尝试在代码中 return 它时, properties
和 parentConfig
.
总是空的
@NodeEntity
public class Config {
@Id
@GeneratedValue
private Long id;
@Relationship(type = "OVERRIDES")
private Config parentConfig;
@Properties(allowCast=true)
private Map<String, String> properties;
....
}
这是我正在测试的基本查询,只是为了看看我是否可以映射到 POJO:
@Query("MATCH (c1:Config) RETURN c1;")
List<Config> findConfigAny(@Param("configName") String configName);
您接近解决方案,但 Neo4j-OGM(Spring Data Neo4j 中用于对象图映射的库)存在技术限制:使用 @Properties
注释时只会保留并加载带有正确分隔符(默认 .
)的前缀(默认属性名称)。所以基本上在你的情况下,它只会加载前缀为 properties.
的属性,而不是所有得到 returned.
的属性
在 Spring Data Neo4j 中,还有可能提供一个 @QueryResult
可以被视为 DTO。您可以使用注释标记中间 class 。请确保此 class 也是您实体扫描的一部分。
@QueryResult
public class ConfigDto {
private String name;
private Map<String, String> properties;
}
如果您将 SDN 存储库方法的 return 类型也更改为此类型
@Query("MATCH p = SHORTESTPATH((c2:Config)<-[:OVERRIDES*]-(c1:Config))"
+ " WHERE c1.name = 'Child' and not (c2)-[:OVERRIDES]->()"
+ " UNWIND NODES(p) as props return props.name as name, PROPERTIES(props) as properties")
List<ConfigDto> configs();
与使用此方法相比,它将 return:
ConfigDto{name='Child', properties={a.exclusive=1, name=parentConfig, a.override=parent value}}
ConfigDto{name='Child', properties={a.exclusiveChild=my value, name=Child, a.override=child value}}
请注意,我编写了一个测试,其中包含一个 "original" Config
对象的持久性,该对象具有如上所示的属性映射,我只是在它们前面加上 a.
前缀。您还可以看到名称也在查询中 属性 映射 return 中,因此该映射包含节点的所有属性。
编辑(保存部分评论)
使用上述解决方案,可以从 Neo4j 加载现有数据。
除了 @Properties
解决方案之外,无法保留任意属性,但这将在您的图表中创建 "prefixed"、"delimited" 属性。例如。使用问题中的代码,您将得到 properties.docker_tag
.
例如,您可以为 Map
编写自己的属性转换器,并从 https://github.com/neo4j/neo4j-ogm/blob/master/core/src/main/java/org/neo4j/ogm/typeconversion/MapCompositeConverter.java 中定位和借鉴一些想法
这是转换器的 link 到 documentation,您应该实现 CompositeAttributeConverter
.
Neo4j-OGM 并不意味着一直在更改属性名称,如果域中存在 属性 和 nameA
,决定保存什么也很复杂 class 本身并且也在这样的 属性 映射中定义。
我正在编写一个应用程序来捕获其他应用程序的配置属性。 Config
是我的主域对象。 Config
对象之间存在层次关系(一个 Config
[:OVERRIDES] 另一个 Config
)。因此,给定一个最底层的 Config
,我需要沿着层次结构一直向上到达最顶层的 Config
,并沿途收集 Config
对象的所有属性,将它们合并为一个最终 Config
。但是我不知道如何使用 Spring 数据来做到这一点。
这是 2 个 Config
对象的架构:
CREATE (c1:Config {name:'ConfigParent'});
SET c2.docker_tag='1.0.0';
SET c2.mem_limit='1gb';
MATCH (c1:Config {name: 'ConfigParent'})
CREATE (c2:Config {name:'ConfigChild'})-[:OVERRIDES]->(c1)
SET c2.docker_tag='1.0.1';
ConfigChild
属性需要与 ConfigParent
合并,ConfigParent
中的任何重复属性都将被覆盖。所以我最后的一组属性应该是:
name='ConfigMerged' //I don't know what this name would be?
docker_tag='1.0.1'
mem_limit='1gb'
Config
中可以有任何 key/value 对,因此不能按名称 return 编辑它们。我已经有了这个 CQL,我认为它可以满足我的要求:
MATCH p = SHORTESTPATH((c2:Config)<-[:OVERRIDES*]-(c1:Config))
WHERE c1.name = 'ConfigChild' and not (c2)-[:OVERRIDES]->()
UNWIND NODES(p) as props return PROPERTIES(props);
JSON 响应如下所示:
[
{
"keys": [
"properties(props)"
],
"length": 1,
"_fields": [
{
"name": "ConfigParent",
"docker_tag": "1.0.0",
"mem_limit": "1gb"
}
],
"_fieldLookup": {
"properties(props)": 0
}
},
{
"keys": [
"properties(props)"
],
"length": 1,
"_fields": [
{
"name": "ConfigChild",
"docker_tag": "1.0.1"
}
],
"_fieldLookup": {
"properties(props)": 0
}
}
]
问题是,我不知道如何将其映射到 POJO。我需要 Config
域对象还是 Properties
域对象?这是实现我目标的最佳 CQL 吗?
更新:我为 Config
提出了带注释的 POJO。但是当我尝试在代码中 return 它时, properties
和 parentConfig
.
@NodeEntity
public class Config {
@Id
@GeneratedValue
private Long id;
@Relationship(type = "OVERRIDES")
private Config parentConfig;
@Properties(allowCast=true)
private Map<String, String> properties;
....
}
这是我正在测试的基本查询,只是为了看看我是否可以映射到 POJO:
@Query("MATCH (c1:Config) RETURN c1;")
List<Config> findConfigAny(@Param("configName") String configName);
您接近解决方案,但 Neo4j-OGM(Spring Data Neo4j 中用于对象图映射的库)存在技术限制:使用 @Properties
注释时只会保留并加载带有正确分隔符(默认 .
)的前缀(默认属性名称)。所以基本上在你的情况下,它只会加载前缀为 properties.
的属性,而不是所有得到 returned.
在 Spring Data Neo4j 中,还有可能提供一个 @QueryResult
可以被视为 DTO。您可以使用注释标记中间 class 。请确保此 class 也是您实体扫描的一部分。
@QueryResult
public class ConfigDto {
private String name;
private Map<String, String> properties;
}
如果您将 SDN 存储库方法的 return 类型也更改为此类型
@Query("MATCH p = SHORTESTPATH((c2:Config)<-[:OVERRIDES*]-(c1:Config))"
+ " WHERE c1.name = 'Child' and not (c2)-[:OVERRIDES]->()"
+ " UNWIND NODES(p) as props return props.name as name, PROPERTIES(props) as properties")
List<ConfigDto> configs();
与使用此方法相比,它将 return:
ConfigDto{name='Child', properties={a.exclusive=1, name=parentConfig, a.override=parent value}}
ConfigDto{name='Child', properties={a.exclusiveChild=my value, name=Child, a.override=child value}}
请注意,我编写了一个测试,其中包含一个 "original" Config
对象的持久性,该对象具有如上所示的属性映射,我只是在它们前面加上 a.
前缀。您还可以看到名称也在查询中 属性 映射 return 中,因此该映射包含节点的所有属性。
编辑(保存部分评论) 使用上述解决方案,可以从 Neo4j 加载现有数据。
除了 @Properties
解决方案之外,无法保留任意属性,但这将在您的图表中创建 "prefixed"、"delimited" 属性。例如。使用问题中的代码,您将得到 properties.docker_tag
.
例如,您可以为 Map
编写自己的属性转换器,并从 https://github.com/neo4j/neo4j-ogm/blob/master/core/src/main/java/org/neo4j/ogm/typeconversion/MapCompositeConverter.java 中定位和借鉴一些想法
这是转换器的 link 到 documentation,您应该实现 CompositeAttributeConverter
.
Neo4j-OGM 并不意味着一直在更改属性名称,如果域中存在 属性 和 nameA
,决定保存什么也很复杂 class 本身并且也在这样的 属性 映射中定义。