Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neo4j 密码查询don';查找多个记录时不返回关系_Neo4j_Cypher - Fatal编程技术网

Neo4j 密码查询don';查找多个记录时不返回关系

Neo4j 密码查询don';查找多个记录时不返回关系,neo4j,cypher,Neo4j,Cypher,我正在写一个搜索食谱的查询。我想返回当前用户交互(喜欢等)以及与查询匹配的配方 此查询正确返回当前用户的所有交互: MATCH (recipe)<-[reaction:REACTS]-(beholder:User {cuid: 'some-id'}) RETURN reaction 我用于按id获取单个配方的查询工作正常: MATCH (recipe:Recipe {cuid: {recipeCuid}}) OPTIONAL MATCH (recipe)-[a:CONTAINS]->

我正在写一个搜索食谱的查询。我想返回当前用户交互(喜欢等)以及与查询匹配的配方

此查询正确返回当前用户的所有交互:

MATCH (recipe)<-[reaction:REACTS]-(beholder:User {cuid: 'some-id'})
RETURN reaction
我用于按id获取单个配方的查询工作正常:

MATCH (recipe:Recipe {cuid: {recipeCuid}})
OPTIONAL MATCH (recipe)-[a:CONTAINS]->(i:Ingredient)
OPTIONAL MATCH (recipe)-[:IS]->(c:Category)
OPTIONAL MATCH (recipe)<-[:AUTHORED]-(u:User)
OPTIONAL MATCH (recipe)<-[reaction:REACTS]-(beholder:User {cuid: {beholderCuid}})
RETURN recipe,
{username: u.username, cuid: u.cuid} AS author,
{love: reaction.love, favorite: reaction.favorite} AS interactions,
collect( DISTINCT {name: i.name, amount: a.amount}) AS ingredients,
collect( DISTINCT {name: c.name}) AS categories
MATCH(配方:配方{cuid:{recipeCuid})
可选匹配(配方)-[a:包含]->(i:成分)
可选匹配(配方)-[:IS]->(c:类别)

可选匹配(配方)尝试将成分和类别收集到集合中,并对这些集合执行检查。
RETURN
子句稍微简化了一点,但首先让我们看看这是否有效

MATCH (recipe:Recipe)
OPTIONAL MATCH (recipe)-[a:CONTAINS]->(i:Ingredient)
OPTIONAL MATCH (recipe)-[:IS]->(c:Category)
OPTIONAL MATCH (recipe)<-[:AUTHORED]-(u:User)
OPTIONAL MATCH (recipe)<-[reaction:REACTS]-(beholder:User {cuid: 'some-id'})
WITH recipe, collect(i) AS ingredients, collect(c) AS categories, u, reaction, beholder
WHERE ALL(
  ingredient IN ['tomato', 'banana']
  WHERE ingredient in ingredients
)
AND ALL(
  category IN ['smoothie']
  WHERE category in categories
)
RETURN DISTINCT recipe,
  {username: u.username, cuid: u.cuid} AS author,
  {love: reaction.love, favorite: reaction.favourite} AS interactions,
  ingredients,
  categories
匹配(配方:配方)
可选匹配(配方)-[a:包含]->(i:成分)
可选匹配(配方)-[:IS]->(c:类别)

可选匹配(配方)Gabor的查询是一个很好的进步,因为它将您的位置移动到后面,而不是保留可选匹配…这是您无法获得正确结果的主要原因

但是,查询仍然需要一些效率改进。首先,如果不立即运行聚合,一行中的多个匹配或可选匹配,尤其是那些将返回多行(成分、类别)的匹配,将影响其余匹配或可选匹配的效率

例如,对于包含3种成分和2个类别的单一配方,在前两个可选匹配完成时,即3 x 2=6行,这意味着其余可选匹配需要在所有6行中执行,但您的意图是每个配方只执行一次,而不是多次

这就是为什么尽快聚合是有用的,因为它可以将每个配方的行数减少到一行,而不是多行(对于配方、成分和类别的每个组合,配方具有单个成分和单个类别)

此外,只有在匹配完所有其他内容后,才能进行向下筛选(基于成分和类别),这意味着您要对肯定会被过滤掉的行运行许多可选的匹配。这是浪费的工作和浪费的数据库点击。最好尽快进行筛选,然后对您知道将返回的行运行所需的其他可选匹配

最后,由于您似乎只希望返回包含特定成分和特定类别的食谱的行,因此我们应该使用成分和类别匹配,而不是可选匹配

对于改进的查询,我推荐如下内容:

MATCH (cat:Category) 
WHERE cat.name IN ['smoothie']
WITH COLLECT(cat) as desiredCategories
MATCH (i:Ingredient)
WHERE i.name IN ['tomato', 'banana']
WITH desiredCategories, COLLECT(i) as desiredIngredients
MATCH (recipe:Recipe)
WHERE ALL(
  category IN desiredCategories
  WHERE (recipe)-[:IS]->(category)
) 
AND ALL(
  ingredient IN desiredIngredients
  WHERE (recipe)-[:CONTAINS]->(ingredient)
)
WITH recipe
MATCH (recipe)-[:IS]->(c:Category)
WITH recipe, COLLECT(c) as categories
MATCH (recipe)-[a:CONTAINS]->(i:Ingredient)
WITH recipe, categories, COLLECT({name: i.name, amount: a.amount}) as ingredients
OPTIONAL MATCH (recipe)<-[:AUTHORED]-(u:User)
// only one author, so okay to use optional matches back to back
OPTIONAL MATCH (recipe)<-[reaction:REACTS]-(beholder:User {cuid: 'some-id'})
RETURN recipe,
  {username: u.username, cuid: u.cuid} AS author,
  {love: reaction.love, favorite: reaction.favourite} AS interactions,
  ingredients,
  categories
匹配(类别:类别)
其中cat.name位于['smoothie']
将收集(cat)作为所需类别
匹配(一:成分)
其中i.name在['tomato','banana']
对于desiredCategories,收集(i)作为DesiredGreditions
匹配(配方:配方)
都在哪里(
所需类别中的类别
其中(配方)-[:IS]->(类别)
) 
诸如此类(
所需添加剂中的成分
其中(配方)-[:包含]->(成分)
)
有菜谱
匹配(配方)-[:IS]->(c:类别)
使用配方,按类别收集(c)
匹配(配方)-[a:包含]->(i:成分)
使用配方、类别、收集({name:i.name,amount:a.amount})作为配料

可选匹配(配方)1。如果从查询中删除
WHERE
子句,结果如何?可能
WHERE
子句过滤掉了
reaction
不为null的所有匹配项。2.这可能没有什么区别,但是在您的第一个查询中,您没有指定
recipe
应该有一个标签
recipe
。当我删除where子句时,它起作用了!有没有办法让它与
WHERE
子句一起工作?如果只保留
WHERE
子句中的一个条件,即只检查
成分
或只检查
类别
,会发生什么情况?删除类别会产生相同的结果;全部为空。去除成分给了我一些正确互动的记录(仅第一条记录)!请记住,如果子句不适用于整个结果集,则它们仅适用于前面的匹配、可选匹配或WITH子句。可选匹配,特别是与WHERE组合,可以产生您不期望的结果,因为这意味着它将根据WHERE子句返回可选匹配的元素,它不会影响以前的行或匹配。在你的例子中,最后一个可选的搭配元素(反应、眼魔)只在配方中添加了番茄和香蕉作为冰沙的配料。使用WITH before WHERE可影响整个结果集。同时在collect()中添加了大量成分。谢谢!我需要研究这个查询才能完全理解它。但在运行它时,我得到了
变量“c”未定义
,尝试将其更改为
cat
,但还是出现了相同的错误。找到了错误,我没有更新:Category上的匹配项。它现在应该运行了。至于研究查询,通常可以看到查询是如何逐块构建的。您可以在不同的位置用RETURN替换(删除查询的其余部分),以查看我们如何构建结果。在这种情况下,背靠背选秀赛也是一种糟糕的做法吗?是的。对于该查询,您可以自己进行测试,看看如果在每个可选匹配之后返回范围内的所有内容,注释掉其余内容,然后继续移动该返回以查看结果如何生成,因为您知道下一个可选匹配必须在所有这些行上运行。更好的方法是尽可能快地在可选匹配之间进行聚合(如果可以的话)。
MATCH (cat:Category) 
WHERE cat.name IN ['smoothie']
WITH COLLECT(cat) as desiredCategories
MATCH (i:Ingredient)
WHERE i.name IN ['tomato', 'banana']
WITH desiredCategories, COLLECT(i) as desiredIngredients
MATCH (recipe:Recipe)
WHERE ALL(
  category IN desiredCategories
  WHERE (recipe)-[:IS]->(category)
) 
AND ALL(
  ingredient IN desiredIngredients
  WHERE (recipe)-[:CONTAINS]->(ingredient)
)
WITH recipe
MATCH (recipe)-[:IS]->(c:Category)
WITH recipe, COLLECT(c) as categories
MATCH (recipe)-[a:CONTAINS]->(i:Ingredient)
WITH recipe, categories, COLLECT({name: i.name, amount: a.amount}) as ingredients
OPTIONAL MATCH (recipe)<-[:AUTHORED]-(u:User)
// only one author, so okay to use optional matches back to back
OPTIONAL MATCH (recipe)<-[reaction:REACTS]-(beholder:User {cuid: 'some-id'})
RETURN recipe,
  {username: u.username, cuid: u.cuid} AS author,
  {love: reaction.love, favorite: reaction.favourite} AS interactions,
  ingredients,
  categories