2017-02-10 14 views
2

У меня есть следующий Neo4j Cypher запрос: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 я ожидаю retrive 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; 
} 

Сейчас этот запрос возвращает правильный список критериев, но неправильный список с пустыми элементами характеристики.

Например, у меня нет никаких характеристик, которые соответствуют этому условию запроса, но в результате я могу увидеть следующую структуру с двумя записями:

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 элементов) характеристик для обеих этих записей (для этих узлов нет связанных характеристик). Но в первой записи у меня есть две пустые характеристики (такая же длина списка и критерии) и 3 пустые характеристики для второй записи.

Что я делаю неправильно и как это исправить?

ответ

1

Это является результатом явного создания карты для значений здесь:

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

Это создает карту и устанавливает значения соответственно, и эти значения, оказываются нулевым, так как ДОПОЛНИТЕЛЬНЫЙ MATCH не смог соответствовать шаблону. Нет ничего плохого в добавлении нулевых значений в карту, и нет ничего, что по сути связывает существование карты с тем, является ли одно (или даже все) ее значений свойств нулевым или не равным нулю.

Для 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, чтобы условно испустить null вместо вашей карты valuedCharacteristic (и weightedCriterion), когда соответствующая переменная равна null. Обрезание с использованием этого будет выглядеть так:

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

Спасибо! Это именно то, что мне нужно. Я использую Neo4j 3.1 – alexanoid