Neo4j Cypher 多个 WITH 关键字

Neo4j Cypher multiple WITH keywords

我有以下 Neo4j Cypher 查询:

MATCH (parentD:Decision)-[:CONTAINS]->(childD:Decision) 
WHERE id(parentD) = {parentDecisionId} 
WITH childD, parentD 
OPTIONAL MATCH (parentD)<-[:DEFINED_BY]-(c:Criterion)<-[:VOTED_ON]-(vg:VoteGroup)-[:VOTED_FOR]->(childD) 
OPTIONAL MATCH (parentD)<-[:DEFINED_BY]-(ch:Characteristic)<-[:SET_ON]-(v:Value)-[:SET_FOR]->(childD) 
WITH childD, {criterion: c,  weight: vg.avgVotesWeight} AS weightedCriterion, {characteristic: ch,  value: v.value} AS valuedCharacteristic 
RETURN childD AS decision, collect(weightedCriterion) AS weightedCriteria, collect(valuedCharacteristic) AS valuedCharacteristics

作为我的 SDN 4 项目的结果,我希望检索 List<DecisionMatrix>

@QueryResult
public class DecisionMatrix {

    private Decision decision;

    private List<WeightedCriterion> weightedCriteria;

    private List<ValuedCharacteristic> valuedCharacteristics;

}

@QueryResult
public class WeightedCriterion {

    private Criterion criterion;

    private Double weight;

}

@QueryResult
public class ValuedCharacteristic {

    private Characteristic characteristic;

    private Object value;
}

现在这个查询 returns 一个正确的标准列表但是一个错误的列表,其中包含一个空的特征元素。

例如,我没有任何符合此查询条件的特征,但在结果中我可以看到包含两条记录的以下结构:

RDBMS : [{criterion=Node[161], weight=4.333333333333333}, {criterion=Node[160], weight=2.1666666666666665}] : [{characteristic=null, value=null}, {characteristic=null, value=null}]

NoSQL : [{criterion=Node[160], weight=4.333333333333333}, {criterion=Node[161], weight=2.5}, {criterion=Node[162], weight=4.2}] : [{characteristic=null, value=null}, {characteristic=null, value=null}, {characteristic=null, value=null}]

结果包含 RDBMS(2 个标准)和 NoSQL(3 个标准)的一组正确标准,但包含一组错误的特征。我希望这两个记录都有一个空的特征列表(0 个元素)(这些节点没有关联的特征)。但是在第一个记录中我有 2 个空特征(列表长度与标准相同)和 3第二条记录的空特征。

我做错了什么以及如何解决?

这是为此处的值显式创建映射的结果:

... {characteristic: ch,  value: v.value} AS valuedCharacteristic ...

这会创建一个映射,并相应地设置值,而这些值恰好为空,因为可选匹配无法匹配模式。将空值添加到地图中并没有错,地图的存在与它的一个(甚至所有)属性 值是否为空没有本质上的联系。

对于 Neo4j 3.1 及更高版本,解决此问题并确保末尾的列表在没有特征时保持为空的最简单方法是完全跳过可选匹配,并改用 pattern comprehension .我们也可以在您使用 :Criterion 和 :VoteGroup 时对您的其他可选匹配做同样的事情。

MATCH (parentD:Decision)-[:CONTAINS]->(childD:Decision) 
WHERE id(parentD) = {parentDecisionId} 
RETURN childD AS decision,
[ (parentD)<-[:DEFINED_BY]-(c:Criterion)<-[:VOTED_ON]-(vg:VoteGroup)-[:VOTED_FOR]->(childD) 
  | {criterion: c,  weight: vg.avgVotesWeight} ] AS weightedCriteria, 
[ (parentD)<-[:DEFINED_BY]-(ch:Characteristic)<-[:SET_ON]-(v:Value)-[:SET_FOR]->(childD) 
  | {characteristic: ch,  value: v.value} ] AS valuedCharacteristics

如果您的模式理解中的模式不存在,则生成的列表将为空。

对于 Neo4j 3.0 及以下版本,您可能必须坚持使用原始查询,但在相应变量为无效的。使用它的片段看起来像:

... CASE WHEN ch IS NULL THEN null ELSE {characteristic: ch,  value: v.value} END AS valuedCharacteristic