我目前正在努力解决有关组合学的问题 对于原型我想尝试neo4j-ogm。
这是我到目前为止设计的域模型:
@NodeEntity
public class Operand {
@GraphId
private Long graphId;
}
@NodeEntity
public class Option extends Operand {
private Long id;
private String name;
@Relationship(type = "CONDITIONED_BY")
private List<Rule> rules = new ArrayList<>();
}
@NodeEntity
public class Operation extends Operand {
@Relationship(type = "COMPOSITION", direction = Relationship.INCOMING)
private Rule composition;
private Operation superOperation;
private Boolean not;
private List<Operand> operands = new ArrayList<>();
}
public class AndOperation extends Operation {
// Relationships named accordingly "AND"
}
public class OrOperation extends Operation {
// Relationships named accordingly "OR"
}
@NodeEntity
public class Rule {
@GraphId
private Long graphId;
@Relationship(type = "COMPOSITION")
private Operation composition;
@Relationship(type = "CONDITIONED_BY", direction = Relationship.INCOMING)
private Option option;
}
这是我的图表的片段:
表示(167079 ^ ...) & (167155 ^ ...)
是否可以在cypher中形成查询,从而产生所有可能的组合?
167079,167155
167079,167092
...
到目前为止,我发现这resource处理了一个远程相关的问题。
您认为这是neo4j的正确使用案例吗?
您是否建议对域模型进行任何更改?
您是否建议使用其他技术?
示例图仅显示原始图的一小部分,我必须使用各种深度和各种封装操作来计算排列。
答案 0 :(得分:1)
是的,我们可以通过收集方程式(两个集合)然后展开每个集合来获得这个。
假设两个集合作为参数传递:
UNWIND {first} as first
UNWIND {second} as second
RETURN first, second
这应该会在两个集合的元素之间为您提供笛卡尔积。
修改
如果知道你有多少AND分支(例如2),你可以像这样形成你的查询:
MATCH (first)<-[:OR*0..]-()<-[:AND]-(root)-[:AND]->()-[:OR*0..]->(second)
WHERE id(root) = 168153
RETURN first, second
(编辑,匹配本身将为您生成笛卡尔积)
对于您不知道有多少AND分支的操作,我不相信您只使用Cypher可以实现这一点,因为我不相信支持动态列。
您可以使用集合执行此操作,但操作会很棘手。
在这种情况下,给定两个集合执行交叉产品的自定义过程非常有用。如果您可以收集AND分支上的所有节点集合,则可以对其运行REDUCE(),对每个集合应用交叉产品过程。
对于操作更多的更复杂的树木,我不相信你能通过Cypher做到这一点。我强烈推荐一个自定义过程,你将拥有更多的控制权,并能够使用条件逻辑,递归和方法调用。