2014-10-06 5 views
0

Я пытаюсь выполнить Neo4j для личного проекта по внедрению системы рекомендаций. В качестве входных и выходных данных система берет несколько строк. Система имеет узлы в виде животных и групп. Связь между животными и группами заключается в том, что животное принадлежит к группе. Животное может принадлежать нескольким группам.Neo4j: сопоставьте три или более отношения с одним динамическим узлом

Ввод может быть любым количеством животных. Вопрос, на который я пытаюсь ответить, - «Какие животные присутствуют в группах, которые содержат все входные животные?»

Пример правильного вывода:

Input: Lion, Parrot, Giraffe 
Output: Elephant, Zebra 
The lion, parrot and giraffe all belong to group 2 and 3. The elephant belongs to group 2 and the zebra belongs to group 3, so they are outputted. 

Мое текущее решение:

Match (:Animal { name: "Parrot" }) 
      -[:BELONGS_TO]->(matchingGroup:Group) 
      <-[:BELONGS_TO]-(:Animal { name: "Lion" }), 
     (:Animal { name: "Giraffe" }) 
      -[:BELONGS_TO]->matchingGroup 
      <-[:BELONGS_TO]-(animalsInMatchingGroup:Animal) 
    Return animalsInMatchingGroup.name AS name, count(animalsInMatchingGroup.name) as matches 
    ORDER BY count(animalsInMatchingGroup.name) DESC 

Проблема: Проблема возникает тогда, когда у меня есть более двух животных в моем запросе. В вышеприведенном вопросе я запрашиваю график, используя утверждения Match, равные количеству входных животных - 1. Мне интересно, знает ли кто-нибудь о лучшем решении этой проблемы, что предотвратит многократное обращение к графу.

Это график. http://s29.postimg.org/inhhvqcd3/Screen_Shot_2014_10_05_at_8_09_23_PM.png

Создать ЗАЯВЛЕНИЕ

CREATE 
(elephant:Animal { name: 'Elephant' }), 
(lion:Animal { name: 'Lion' }), 
(tiger:Animal { name: 'Tiger' }), 
(giraffe:Animal { name: 'Giraffe' }), 
(parrot:Animal { name: 'Parrot' }), 
(zebra:Animal { name: 'Zebra' }), 
(group1:Group { name: 'Group 1' }), 
(group2:Group { name: 'Group 2' }), 
(group3:Group { name: 'Group 3' }), 
(group4:Group { name: 'Group 4' }), 
(group5:Group { name: 'Group 5' }), 
elephant-[:BELONGS_TO]->group2, 
elephant-[:BELONGS_TO]->group3, 
lion-[:BELONGS_TO]->group1, 
lion-[:BELONGS_TO]->group2, 
lion-[:BELONGS_TO]->group3, 
parrot-[:BELONGS_TO]->group2, 
parrot-[:BELONGS_TO]->group3, 
parrot-[:BELONGS_TO]->group5, 
giraffe-[:BELONGS_TO]->group2, 
giraffe-[:BELONGS_TO]->group3, 
giraffe-[:BELONGS_TO]->group4, 
tiger-[:BELONGS_TO]->group5, 
zebra-[:BELONGS_TO]->group4, 
zebra-[:BELONGS_TO]->group3 

Спасибо за вашу помощь.

Cheers, Cam.

ответ

0

Вы можете попробовать это:

WITH ['Parrot', 'Lion', 'Giraffe'] AS names 
MATCH (:Animal { name: head(names)})-[:BELONGS_TO]->(g:Group) 
WITH g,names 
MATCH (g)<-[:BELONGS_TO]-(a:Animal) 
WITH g,collect(a.name) AS animals,names 
WHERE ALL (n IN names 
      WHERE n IN animals) 
RETURN g.name, animals,names,size(animals) 

Смотрите эту консоль: http://console.neo4j.org/r/vd2mba

+0

Есть некоторые хорошие идеи в этом запросе, но выход неправильно. Спасибо за понимание, я посмотрю, могу ли я сократить запрос с помощью параметра WITH. Один вопрос: имеет ли использование предложения IN тот же самый удар производительности при использовании его в инструкции SQL? –

Смежные вопросы