我使用CypherDSL从Neo4j检索特定节点;但返回的实体缺少其@Relationship属性。该实体类似于:
@Node
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(exclude = {"children", "visibleEntities"})
@ToString(exclude = {"children", "visibleEntities"})
public class VisibilityGroup {
public static final String CAN_SEE_REL_TYPE ="CAN_SEE";
public static final String CONTAINS_REL_TYPE ="CONTAINS";
public static final String ENTITY_ID_PROPERTY= "entityId";
@DynamicLabels
@Singular(ignoreNullCollections = true)
private List<String> labels;
@Property("name")
private String nodeName;
@Property(ENTITY_ID_PROPERTY)
private UUID entityId;
@Id
@GeneratedValue(generatorClass = UUIDStringGenerator.class)
private String id;
@Relationship(type = CONTAINS_REL_TYPE, direction = Relationship.Direction.OUTGOING)
@Builder.Default
private Set<VisibilityGroupRelationship> children = new HashSet<>();
@Relationship(type = CAN_SEE_REL_TYPE, direction = Relationship.Direction.OUTGOING)
@Builder.Default
private Set<VisibilityGroupRelationship> visibleEntities = new HashSet<>();
........
}
现在:如果我使用ReactiveCrudRepository.findById(ID id),则对象具有正确初始化的子对象和visibleEntities,但如果我使用CypherDSL获取它,则它们都为null。
下面是我的repo代码:
default Mono<VisibilityGroup> findEntity(UUID originEntityId, String originType,
UUID targetEntityId, String targetType,
boolean useContains){
Node targetNode = Cypher.node(targetType)
.named("target")
.withProperties(VisibilityGroup.ENTITY_ID_PROPERTY,
Cypher.literalOf(targetEntityId.toString()));
Node originNode = Cypher.node(originType)
.named("origin")
.withProperties(VisibilityGroup.ENTITY_ID_PROPERTY,
Cypher.literalOf(originEntityId.toString()));
Relationship relationship = useContains ?
originNode.relationshipTo(targetNode, VisibilityGroup.CAN_SEE_REL_TYPE,
VisibilityGroup.CONTAINS_REL_TYPE).unbounded() :
originNode.relationshipTo(targetNode, VisibilityGroup.CAN_SEE_REL_TYPE).unbounded();
SymbolicName permissionVariable = Cypher.name("p");
ResultStatement statement = Cypher.match(relationship)
.where(....)
.returningDistinct(targetNode).build();
return findOne(statement);
}
我知道,我可以很容易地修复它,将最后一行替换为:
return findOne(statement).flatMap(visibilityGroup -> findById(visibilityGroup.getId()));
但我想知道这是否正常,或者我是否滥用了CypherDSL。提前谢谢你。
更新
我添加了模型和预期结果的文本描述。所有节点都用“CAN_SEE”或“CONTAINS”关系绑定在一起,定义了一个可见性图。只有管理员可以通过CONTAINS关系“看到”;所有用户都可以通过“CAN_SEE”关系进行查看。所提出的存储库方法发现源节点(通常是用户)CAN_SEE*(或CAN_SEE|CONTAINS*)目标节点,这很好用。返回的节点是请求的目标节点,如果可见的话。我需要的是返回的目标节点包含ITS邻居作为属性:
1.在visibleEntities属性中,哪些节点直接(1跳)绑定到具有CAN_SEE关系的目标节点;
1.在children属性中,哪些节点通过CONTAINS关系直接(1跳)绑定到他。
1条答案
按热度按时间mec1mxoz1#
请在退货条款中使用以下内容:
基本上,当使用自定义查询时,你必须做的是将返回的子图整形为每个实体一条记录(这是SDN通常对生成的查询所做的),这里描述:每个根节点获取一条记录,作为Cypher-DSL示例,在使用复杂、动态的自定义查询但仍返回域类型下
我是Cypher-DSL的作者和SDN的共同维护者,所以感谢您使用两者:)
请注意,我在与您的模型相同的方向上查询关系,从目标节点的PoV(它们从其视图传出)
这个条件当然会导致无效的密码,因为
p
是未定义的,但我想这个想法是明确的。当使用
CONTAINS
关系时,这将生成如下内容你可以利用你已经匹配了所有类型的事实
或者不用的时候,像这样
请测试优化,我不确定是否总是包含所有的关系时,使用
|
或运算符从我的头顶部。