我有这个查询返回非常快,0.5秒并返回所有303个预期的记录.注意:"Woka"在这里的意思是"书".
MATCH (p:Publisher)-[r:PUBLISHED]->(w:Woka)<-[s:AUTHORED]-(a:Author),
(l:Language)-[t:USED]->(w:Woka)-[u:INCLUDED]->(b:Bisac)
WHERE (a.author_name = 'Camus, Albert')
RETURN w.woka_id as woka_id, p.publisher_name as publisher_name, w.woka_title as woka_title, a.author_name as author_name, l.language_name as language_name, b.bisac_code as bisac_code, b.bisac_value as bisac_value
ORDER BY woka_id;
Run Code Online (Sandbox Code Playgroud)
我想添加更多信息,例如说明.我在语言和描述以及描述和书籍(Woka)之间创建了描述节点并且创建了关系.下面的查询将所有描述都返回为null,但仅返回60个记录而不是303.这是因为并非所有书籍都有描述.执行时间仍然可以,0.3秒.
MATCH (p:Publisher)-[r:PUBLISHED]->(w:Woka)<-[s:AUTHORED]-(a:Author),
(l:Language)-[t:USED]->(w:Woka), (b:Bisac)<-[u:INCLUDED]-(w:Woka),
(d:Description)-[v:HAS_DESCRIPTION]-(w)
WHERE (a.author_name = 'Camus, Albert')
RETURN w.woka_id as woka_id, p.publisher_name as publisher_name, w.woka_title as woka_title, a.author_name as author_name, l.language_name as language_name, b.bisac_code as bisac_code, b.bisac_value as bisac_value, d.description as description
ORDER BY woka_id;
Run Code Online (Sandbox Code Playgroud)
但是我知道从结果集中遗漏了一些记录,50和303之间的差异确实有描述.我使用OPTIONAL构建另一个查询,但是这个(如下所示)永远不会返回,永远运行.
MATCH (p:Publisher)-[r:PUBLISHED]->(w:Woka)<-[s:AUTHORED]-(a:Author),
(l:Language)-[t:USED]->(w:Woka)-[u:INCLUDED]->(b:Bisac)
OPTIONAL MATCH (d:Description)-[v:HAS_DESCRIPTION]-(w:Woka)-[:AUTHORED]-(a:Author)
WHERE (a.author_name = 'Camus, Albert')
RETURN w.woka_id as woka_id, p.publisher_name as publisher_name, w.woka_title as woka_title, a.author_name as author_name, l.language_name as language_name, b.bisac_code as bisac_code, b.bisac_value as bisac_value, d.description as description
ORDER BY woka_id;
Run Code Online (Sandbox Code Playgroud)
不知道如何改进查询以获取存在的可选描述,并且当303记录的原始结果集不存在时为空?
我想我们前一段时间已经有了这次谈话.
你必须降低你的中间基数
在你的人际关系中使用指示
不要重复你已经解决的模式,比如
OPTIONAL MATCH (d:Description)-[v:HAS_DESCRIPTION]-(w:Woka)-[:AUTHORED]-(a:Author)
Run Code Online (Sandbox Code Playgroud)
应该
OPTIONAL MATCH (d:Description)-[v:HAS_DESCRIPTION]-(w)
Run Code Online (Sandbox Code Playgroud)
如果您匹配长路径,则会在两者之间创建大量潜在匹配项,对于每个行,执行下一个匹配项,如果它们创建多个行,则每个行都会得到一个rows1*rows2*rows3
所以你必须使用其中的任何一个DISTINCT或聚合来尽可能地降低基数.
只是为你的第一个例子展示它,一次用DISTINCT,一次collect.这里可能没有必要,但它仅用于演示,因为示例足够小.
MATCH (p:Publisher)-[r:PUBLISHED]->(w:Woka)<-[s:AUTHORED]-(a:Author)
WHERE (a.author_name = 'Camus, Albert')
WITH DISTINCT w,a,p
MATCH (l:Language)-[t:USED]->(w)
WITH w,a,p, collect(l) as languages
MATCH (w)-[u:INCLUDED]->(b:Bisac)
RETURN w.woka_id as woka_id, w.woka_title as woka_title,
p.publisher_name as publisher_name,
a.author_name as author_name,
[l in languages | l.language_name] as language_names,
b.bisac_code as bisac_code, b.bisac_value as bisac_value
ORDER BY woka_id;
Run Code Online (Sandbox Code Playgroud)
你正确使用,OPTIONAL MATCH但你必须考虑到潜在的额外行数是多重的.
OPTIONAL MATCH的另一种选择是使用路径表达式和解构,例如:
RETURN w.woka_id as woka_id, w.woka_title as woka_title,
[p in ()<-[:HAS_DESCRIPTION]-(w) | head(nodes(p)).description] as descriptions
Run Code Online (Sandbox Code Playgroud)