简体   繁体   English

Neo4j / Cypher-获取分层数据并将其转换为树时,如何将可选匹配项与路径相关联?

[英]Neo4j / Cypher - How to associate an optional match with path when getting hierarchical data and converting to tree?

I'm not sure if that title makes complete sense, but here is what I'm trying to do. 我不确定该标题是否完全有意义,但这就是我想要做的。

I have the following query that works fine: 我有以下工作正常的查询:

MATCH (n:Thing)-[:has_child*0..]->(m) 
WHERE NOT ()-[:has_child]->(n)
WITH n, m 
ORDER BY n.name, m.name 
MATCH p=(n:Thing)-[:has_child*0..]->(m) 
WITH COLLECT(p) AS ps 
CALL apoc.convert.toTree(ps) yield value 
RETURN value

I also have the following query that is also fine which is executed in another part of the application (because I can't figure out how to to it at once): 我也有以下查询也可以在应用程序的另一部分中执行(因为我无法立即知道如何执行该查询):

MATCH (n:Thing {name: {nameParam}})<-[:has_child*]-(m:Thing 
      {btogstate: {btogstateParam}})
RETURN m

So what is happening in the second query is that it is looking up the chain to see if btogstate is set to a certain value. 因此,第二个查询中发生的事情是它正在查找链以查看btogstate是否设置为某个值。 What I'd like to do is combine the two. 我想做的就是将两者结合起来。

Does anyone know how I could put the second query into the first one so that when accessing the tree (value) that I would know that that record has or does not have the value I was querying for? 有谁知道我如何将第二个查询放到第一个查询中,以便在访问树(值)时我会知道该记录具有或不具有我要查询的值?

Hopefully that makes sense. 希望这是有道理的。 I know this is probably not a common issue. 我知道这可能不是一个普遍的问题。

Update to clarify question 更新以澄清问题

Let's say we have some hierarchical data that looks like this, and in the DB it looks like (pseudo) (asdf)-[:has_child]->(qwer)-[:has_child]-> and so on: 假设我们有一些看起来像这样的分层数据,并且在数据库中看起来像(pseudo)(asdf)-[:has_child]->(qwer)-[:has_child]->,依此类推:

--asdf
   -qwer
     -wert
       -erty
--rtyu
   -yuio

Now let's say that we need to know if 'erty' has anything up it's relational chain that has the property of btogstate set to false, and let's say that qwer does in fact have this property set to false. 现在让我们说,我们需要知道“ erty”是否存在关系链上的东西,且关系链的btogstate属性设置为false,而qwer实际上确实将此属性设置为false。

Then the question is: how can the query be structured in a way that when you read the results (value) you know that 'erty' had a parent that had btogstate set to false? 然后的问题是:如何构造查询,以便在读取结果(值)时知道“ erty”的父项的btogstate设置为false?

Are you searching something like that : 您是否正在搜索类似的内容:

MATCH p=(n:Thing)-[:has_child*0..]->(m) 
WHERE NOT ()-[:has_child]->(n) AND
      any(node IN NODES(p) WHERE node.btogstate = $btogstateParam )
WITH COLLECT(p) AS ps 
CALL apoc.convert.toTree(ps) yield value 
RETURN value

Like Tom said, I have done a refactoring on the first part of your query (combine the path and the where clause). 就像汤姆所说的那样,我已经对查询的第一部分进行了重构(结合路径和where子句)。

And to combine your 2 queries, I have used the any function. 为了结合您的2个查询,我使用了any函数。

Cheers. 干杯。

What you are actually looking for - I think - is setting a temporary property that will only show-up in your result. 我想您实际上正在寻找的是设置一个仅会在您的结果中显示的临时属性。 Now, you could actually do that (outside Neo4j) when processing the tree after doing the query. 现在,您可以在执行查询后处理树时实际执行此操作(在Neo4j外部)。 If you want to do it in Neo4j itself the way I would do it is with three queries : 如果要在Neo4j本身中执行此操作,请使用以下三个查询:

MATCH (m:Thing)<-[:HAS_CHILD*0..]-(n:Thing {btogstate: "true"})
WHERE m <> n
SET m.hasit = "yes";

MATCH (n:Thing)-[:HAS_CHILD*0..]->(m) 
WHERE NOT ()-[:HAS_CHILD]->(n)
WITH n, m 
ORDER BY n.name, m.name
MATCH p=(n)-[:HAS_CHILD*0..]->(m)
WITH COLLECT(p) AS ps
CALL apoc.convert.toTree(ps) yield value 
RETURN value;

MATCH (m:Thing)
REMOVE m.hasit;

A Cypher expert (please chime in :-) can probably do this in one statement. 一位Cypher专家(请在:-钟声中)可以用一条语句完成此操作。 I think that would however not improve the readability. 我认为这不会提高可读性。

Hope this helps, Tom 希望这会有所帮助,汤姆

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM