Фильтр на основе свойств связанных узлов

У меня есть ситуация, когда я пытаюсь отфильтровать узлы, которые не связаны с узлами с определенным свойством. Например, у меня есть запрос, который дает мне всех людей, но я хочу отфильтровать только те, у которых есть собаки с коричневой шерстью. Я хотел бы сделать что-то вроде этого:

//For simplicity's sake, assume nodes 1,2,3 are the potentials I care about
START person=node(1,2,3)  
WHERE person-[:has]->(dog{furColor:"Brown"})  // <-- would be nice to use
RETURN person

Однако это не работает. Парсер явно говорит мне:

Свойства элементов шаблона не разрешены в ПОИСКПОЗ.

(Забавно, что он ссылается на «ПОИСКПОЗ», когда я использую «ГДЕ», но что угодно). Таким образом, вы не можете ссылаться на свойства узлов таким образом. Какие еще варианты у меня есть? Я смог эмулировать то, что хочу, добавив предложение MATCH...

START person=node(1,2,3) 
MATCH person-[:has]->dog
WHERE dog.furColor! = "Brown"
RETURN person

... но мне кажется странным и неэффективным, что я должен СООТВЕТСТВОВАТЬ дополнительным путям, а затем снова отфильтровывать их. Есть ли другой способ?


person ean5533    schedule 15.02.2013    source источник


Ответы (2)


я боюсь, что нет другого способа, чем использовать предложение WHERE в вашем графическом дизайне.

но учитывая, что вы можете измениться, и вы действительно этого хотите, вы можете сделать свойство furColor типом отношения к узлу Brown. поэтому вместо того, чтобы хранить информацию в свойстве, вы можете создать дополнительные узлы для всех цветов, а затем просто связать узлы собаки с отношением типа furColor к этим узлам цвета. чем запрос будет быстрее для предложения MATCH, такого как MATCH person-[:has]->dog-[:furColor]->brown (когда вы также указываете коричневый узел на этапе START)

person ulkas    schedule 18.02.2013
comment
Интересная идея. Я не думаю, что это подходит для реальной проблемы, над которой я работаю, но это решение стоит рассмотреть. Спасибо. - person ean5533; 19.02.2013
comment
К вашему сведению, есть возможность использовать WHERE сразу после предложения START. но в этом конкретном сценарии вы не можете, так как узел собаки указан в части MATCH, в противном случае, если он может быть указан в предложении START, вы можете фильтровать с помощью WHERE. - person ulkas; 19.02.2013

Вы можете попробовать это, но сравните это с производительностью матча.

выражения пути в where возвращают набор путей, с функциями набора extract и предикатом набора all вы можете работать с этим набором путей.

START person=node(1,2,3)  
WHERE ALL(dog in extract( path in person-[:has]->() : last(path) // last node of path
           WHERE dog.furColor! = "Brown"
         )
RETURN person
person Michael Hunger    schedule 20.02.2013