2014-10-15 2 views
1

Скажем, у меня есть меню для пиццы, где каждый тип пиццы представлен в виде узла с меткой «Пицца», а каждая вершина - это узел с меткой «Топпинг». Чтобы получить всю пиццу с пепперони, напишите следующий запрос: MATCH (p: Pizza) - [: HAS] -> (t: Topping {type: "pepperoni"}) return p.
Тогда скажите, что у меня есть набор пользователей, которые могут указать свои любимые пиццы. MATCH (u: Пользователь) - [: HAS_FAVORITE] -> (p: Pizza).Узлы соответствия Cypher, которые имеют отношения ко всем узлам, соответствующим некоторым критериям

Каков наилучший способ найти пользователей, которые любят ВСЕ пиццы с пепперони?

Заранее благодарим за ваше время.

ответ

1

Это, как найти с пепперони долива всех отдельных пользователей, которые, как и любой пиццы (ы):

MATCH (u:User)-[:HAS_FAVORITE]->(p:Pizza)-[:HAS]->(t:Topping {type : "pepperoni"}) 
RETURN DISTINCT u; 

Это один из способов, чтобы найти все различные пользователей, которые, как и все пиццы (ы) с пепперони долива:

MATCH (p:Pizza)-[:HAS]->(t:Topping { type : "pepperoni" }) 
WITH COLLECT(p) AS ps 
MATCH (u:User)-[:HAS_FAVORITE]->(q:Pizza) 
WITH u, COLLECT(q) AS qs, ps 
WHERE ALL (x IN ps WHERE x IN qs) 
RETURN u; 
+0

Производительность медленная, потому что она сканирует, собирает и оценивает каждый любимый. Я опубликовал решение, которое оценивает только избранных, имеющих pepperoni. Для первоначального совпадения используется индекс, и для поиска фаворитов используются взаимные обходы. –

+0

Да, мой подход был всего лишь одним из способов сделать это и был в основном подходом грубой силы. Я рад, что вы нашли более эффективный подход. Это очень похоже на то, что произошло со мной позже, после того как я отправил свой ответ. – cybersam

+0

Кстати, вы можете принять свой собственный ответ, если это лучше всего подходит для вас. – cybersam

2

Следующий метод сравнивает количество избранных пользователя, имеющих пепперони с графом всех пицц с пепперони. Он хорошо работает, потому что он соответствует использованию обхода индекса и отношений для сбора только избранных пользователей, имеющих pepperoni. Ответ, отправленный киберсамом, медленный, потому что он должен выполнить полное сканирование всех избранных.

MATCH (p:Pizza)-[:HAS]->(t:Topping { type : "pepperoni" }) 
WITH COUNT(p) AS pCnt, COLLECT(p) AS pCol 
UNWIND pCol as pPep 
MATCH (u:User)-[:HAS_FAVORITE]->(pPep) 
WITH u, COUNT(*) as fCnt, pCnt 
WHERE fCnt = pCnt 
RETURN u 
Смежные вопросы