1
votes

I'm using a graph database to establish a relationship between folders, their children and users (be it owners or sharers of the folder).

Here is an example of my structure. Where orange are folders and blue are users. -

graph db structure

What I want my query to achieve: It should return direct children of the folder under query, and while doing so determine if the child folder being returned is being shared.

My query

MATCH (:Folder { name: 'Nick Hamill' })-[:CHILD]->(children:Folder)

WITH children

OPTIONAL MATCH path = (children)<-[*]-(:User)

UNWIND RELATIONSHIPS(path) AS r WITH children, r

WHERE TYPE(r) = 'SHARES'

RETURN children AS model, COUNT(r) > 0 AS shared

So the query works brilliantly (perhaps a little optimisation needed?) when there is a related user (see below), however, the query fails to return any result if there is no user relationship. I personally can't see why this is because it's an optional match, and surely the count could just return empty?

╒══════════════════════════════════════════════════════════════════════╤════════╕
│"model"                                                               │"shared"│
╞══════════════════════════════════════════════════════════════════════╪════════╡
│{"name":"Dr. Denis Abshire","created_at":"2019-10-11 13:54:58","id":"c│true    │
│f5e084f-d963-35d3-9c6f-fe29b86f6d43","updated_at":"2019-10-11 13:54:58│        │
│"}                                                                    │        │
└──────────────────────────────────────────────────────────────────────┴────────┘

The query should be relatively self-explanatory but for the sake of clarity here's some expected outputs -

| Query Folder         | Returned Folder  | Shared? |
|----------------------|------------------|---------|
| Miss Dessie Oritz II | Nick Hamill      | TRUE    |
| Nick Hamill          | Dr Denis Abshire | TRUE    |
| Samara Russell       | Shemar Huels PhD | FALSE   |
| Shemar Huels PhD     | Hazle Ward       | FALSE   |

I'm running neo4j 3.5.11 community edition. I feel like this should be a fairly easy solution, I'm just meeting the limits of my extremely limited cypher knowledge.

Appreciate any help!

1
You should tell us which version of the language you are using and provide some examples of expected results on the provided databaseSterconium
@Sterconium - thanks, I've added an example result and versionChris
I saw it, but what about the other folders? What should it return with, say, "Samara Russel" ?Sterconium

1 Answers

2
votes

I don't undertsand why you are using this in your query :

OPTIONAL MATCH path = (children)<-[*]-(:User)
UNWIND RELATIONSHIPS(path) AS r WITH children, r
WHERE TYPE(r) = 'SHARES'

With (children)<-[*]-(:User) you are searching all the path (without restriction on its size) between the children & User nodes. And with the WHERE TYPE(r) = 'SHARES' you only want the SHARES relationship ...

So your query will work on this kind of pattern : (children)<-[:CHILD]-(:Folder)<-[:CHILD]-(:Folder)<-[:SHARES]-(:User)

Is it what you want ?

If so, can you try this query :

MATCH (:Folder { name: 'Nick Hamill' })-[:CHILD]->(children:Folder)
RETURN children AS model, size((children)<-[:CHILD*0..]-(:Folder)<-[:SHARES]-(:User)) > 0 AS shared