# Find all paths from node without duplicated

**URL:** <https://community.neo4j.com/t/find-all-paths-from-node-without-duplicated/60981>\
**Category:** Neo4j Graph Platform\
**Tags:** browser, cypher\
**Created:** [February 19, 2023, 10:32pm UTC](https://community.neo4j.com/t/find-all-paths-from-node-without-duplicated/60981 "2023-02-19T22:32:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dragonprod](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@Dragonprod](https://community.neo4j.com/u/Dragonprod)\
**Post date:** [February 19, 2023, 10:32pm UTC](https://community.neo4j.com/t/find-all-paths-from-node-without-duplicated/60981/1 "2023-02-19T22:32:51Z")

</div>

Hello.

I have graph:

```auto
CREATE (a:Item {id: "1"}), (b:Item {id: "2"}), (c:Item {id: "3"})

MATCH (a:Item {id: "1"}), (b:Item {id: "2"})
CREATE (a)-[:a]->(b)

MATCH (a:Item {id: "1"}), (b:Item {id: "2"})
CREATE (b)-[:a]->(a)

MATCH (a:Item {id: "2"}), (b:Item {id: "3"})
CREATE (a)-[:b]->(b)

MATCH (a:Item {id: "2"}), (b:Item {id: "3"})
CREATE (b)-[:a]->(a)

```

I want to get all paths from given node and filter them by relationship. My cypher is:

```auto
MATCH paths = (from:Item {id: '1'}) - [relations*] -> (to:Item)
WHERE ALL(r IN relations WHERE type(r) IN ['a', 'b'])
AND ALL(r IN relations WHERE startNode(r) <> to AND endNode(r) <> from) 
AND (to:Item) - [:a|b] -> () 
WITH {end: to.id, components: [i in relationships(paths) | {id: endNode(i).id, rel_type: type(i)}]} AS result 
RETURN result

```

The result of this cypher is:

```auto
[
  {
    "components": [
      {
        "rel_type": "a",
        "id": "2"
      }
    ],
    "end": "2"
  }
  {
    "components": [
      {
        "rel_type": "a",
        "id": "2"
      },
      {
        "rel_type": "b",
        "id": "3"
      }
    ],
    "end": "3"
  }
]

```

How can I re-write my cypher to avoid first element in array. The correct output, that I want is:

```auto
{
  "components": [
    {
      "rel_type": "a",
      "id": "2"
    },
    {
      "rel_type": "b",
      "id": "3"
    }
  ],
  "end": "3"
}

```

---

<div class="post-metadata">

**Author:** ![glilienfield](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/glilienfield/32/27534_2.png) [@glilienfield](https://community.neo4j.com/u/glilienfield)\
**Post date:** [February 20, 2023, 4:45am UTC](https://community.neo4j.com/t/find-all-paths-from-node-without-duplicated/60981/2 "2023-02-20T04:45:18Z")

</div>

I am assuming you don't want a path that is a segment of any other path. If so, the following query filters those segments out. It is the first approach I thought of that seemed straight forward. Not sure how it will scale for large number of long paths, because each path has to be compared against each other path.

```auto
MATCH paths = (from:Item {id: '1'}) - [*] -> (to:Item)
WHERE ALL(r IN relationships(paths) WHERE type(r) IN ['a', 'b'])
AND ALL(r IN relationships(paths) WHERE startNode(r) <> to AND endNode(r) <> from) 
AND (to:Item) - [:a|b] -> () 
WITH {end: to.id, components: [i in relationships(paths) | {id: endNode(i).id, rel_type: type(i)}]} as result_map
WITH result_map, [i in result_map.components|i.id] as result_ids
WITH collect({map:result_map, ids:result_ids}) as results
UNWIND results as result
WITH result
WHERE none(y in results where y <> result and all(x in result.ids where x in y.ids)) 
RETURN result.map as result

```

 ![Screen Shot 2023-02-19 at 11.45.43 PM](https://us1.discourse-cdn.com/flex021/uploads/neo4jcommunity/original/3X/2/f/2fe7ae73fa5655844188bf5e4f9fb6e349dc38b7.png)

---

<div class="post-metadata">

**Author:** ![Dragonprod](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@Dragonprod](https://community.neo4j.com/u/Dragonprod)\
**Post date:** [February 20, 2023, 6:40pm UTC](https://community.neo4j.com/t/find-all-paths-from-node-without-duplicated/60981/3 "2023-02-20T18:40:54Z")

</div>

Working fine for me. Thanks you

---

<div class="post-metadata">

**Author:** ![AlexanderIv](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/alexanderiv/32/27685_2.png) [@AlexanderIv](https://community.neo4j.com/u/AlexanderIv)\
**Post date:** [February 21, 2023, 1:02pm UTC](https://community.neo4j.com/t/find-all-paths-from-node-without-duplicated/60981/4 "2023-02-21T13:02:18Z")

</div>

> [@glilienfield](#):
>
> `WHERE none(y in results where y <> result and all(x in result.ids where x in y.ids))`

Can you please explain why `none()` and `all()` are nested into one-another? Would the filter be evaluated differently if it was `none(...) AND all(...)`?

---

<div class="post-metadata">

**Author:** ![glilienfield](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/glilienfield/32/27534_2.png) [@glilienfield](https://community.neo4j.com/u/glilienfield)\
**Post date:** [February 21, 2023, 3:36pm UTC](https://community.neo4j.com/t/find-all-paths-from-node-without-duplicated/60981/5 "2023-02-21T15:36:29Z")

</div>

It needs to be nested. What it does is to filter out each path that is a segment of another path in the result set that is generated from your query.

Following the third 'with' and 'unwind', each row consists of one result and the result\_map collection. The 'where' clause is evaluated for each result, to determine if it should be passed through. The outer 'none' predicate loops through each of the results to make sure 'none' of them meet the inner predicate, which is to test if the current results is a segment of any of the other results. This is determined by the inner 'all' predicate, which tests that the list of 'ids' for the current result being tested is not entirely contained in the list of 'ids' from the result of the current iteration of the outer 'none' predicate.

In summary, for a given 'result', we are looping through all the results to ensure 'none' of them contain 'all' of the 'ids' of the current result being tested.
