Ваш запрос не выполняется, потому что вы просите Neo4j найти человека, у которого есть навык, то есть как минимум 3 навыка одновременно.Очевидно, что, учитывая навык n, это никогда не будет java, mysql и html.(Я предполагаю, что вы используете содержимое для «удаления» любой информации о версии, которую они могли добавить к названию навыка, например, javaee или java 8. Просто помните, что это также будет соответствовать javascript. Однако я бы порекомендовал вам получать эти данные в Neo4j, чтобыпусть он разберет общее имя в отдельном поле. Если вы рассматриваете имя как массив умений, то у вас, вероятно, нет совпадений, и ваша схема слишком хрупкая, чтобы делать с ней что-нибудь полезное)
Я бы порекомендовалэтот шаблон соответствия, так что Neo4j проверяет наличие любого действительного узла навыка
MATCH (n:Skill)<--(n1:PannaResume)
WITH n1, COLLECT(n.name) as skills
WHERE ANY(name in skills WHERE name contains "html")
AND (ANY(name in skills WHERE name contains "java")
OR ANY(name in skills WHERE name contains "mysql")
)
OR (
(ANY(name in skills WHERE name contains "c")
OR ANY(name in skills WHERE name contains "mssql")
))
, конечно, чем точнее, тем лучше.Это будет работать намного лучше.
MATCH (n1:PannaResume)-[:has_skill]->(:Skill {name : "html"})
WHERE ((n1)-[:has_skill]->(:Skill {name : "java"}) AND (n1)-[:has_skill]->(:Skill {name : "mysql"}))
OR ((n1)-[:has_skill]->(:Skill {name : "c"}) AND (n1)-[:has_skill]->(:Skill {name : "mssql"}))
RETURN n1
Но вы также можете немного упростить (и упростить планировщик Cypher), разделив ваш запрос на набор отдельных запросов, и объединить результаты, подобные этим
MATCH (n1:PannaResume)-[:has_skill]->(:Skill {name : "html"})
WHERE (n1)-[:has_skill]->(:Skill {name : "java"})
AND (n1)-[:has_skill]->(:Skill {name : "mysql"})
RETURN n1
UNION
MATCH (n1:PannaResume)-[:has_skill]->(:Skill {name : "html"})
WHERE (n1)-[:has_skill]->(:Skill {name : "c"})
AND (n1)-[:has_skill]->(:Skill {name : "mssql"})
RETURN n1
Это должно быть эквивалентно предыдущим запросам, но может быть более эффективным в зависимости от того, что вы делаете / версия Neo4j.WITH будет разбивать запрос на несколько этапов, поэтому планировщик Cypher сначала найдет узлы навыков, а затем найдет человека, связанного с этими навыками.
MATCH (html:Skill {name : "html"}), (java:Skill {name : "java"}), (c:Skill {name : "c"}), (mysql:Skill {name : "mysql"}), (mssql:Skill {name : "mssql"})
WITH *
MATCH (n1:PannaResume)-[:has_skill]->(html)
WHERE ((n1)-[:has_skill]->(java) AND (n1)-[:has_skill]->(mysql)
OR ((n1)-[:has_skill]->(c) AND (n1)-[:has_skill]->(mssql)
RETURN n1
Если вам нужно беспокоиться об эффективности,Вы должны поэкспериментировать с разными запросами, используя ключевое слово PROFILE .Главное, что вы пытаетесь сделать, это минимизировать количество строк, которое производит каждая «стадия» запроса, поскольку каждая последующая стадия будет умножена на количество строк, произведенных предыдущей стадией.(Планировщик Cypher может выбрать выполнение нескольких запросов параллельно, а затем найти их пересечение. Поэтому не очевидно, как изменение Cypher повлияет на план. PROFILE покажет неэффективность вашего запроса, поэтому обратите внимание на шаги свысокая dbhits или результат в большом количестве строк.)