Search code examples
neo4jcyphergraph-databases

Cypher query returns no results


I have the query which finds the shortest path between 2 nodes. These nodes are labeled as devices but they are also connected to Apps nodes. So I have 2 app_ids and I would like by these ids find all the connections between the 2 devices related to these app_ids as well as the information about all the affected devices in these connections. So I had this query:

WITH ["000001", "000002"] as IDS
UNWIND IDS as app_ids
MATCH (d:Device)-[:DEV_APP]->(a:Apps {app_id: app_ids})
WITH COLLECT(d) as device, COLLECT(distinct a) as app
WITH device[1] as first, device[7] as second, app
WITH first.device_id AS id1, second.device_id as id2, application
MATCH path=allShortestPaths((d1:Device {device_id:id1})-[:DEV_COL1|DEV_COL2|:DEV_COL3*..5]->(d2:Device {device_id:id2}))
RETURN path, application

This query returns all the paths between the nodes, however, I also need the data about all the connected apps to affected devices. While as the results I only get all the Devices nodes data plus 2 Apps nodes data. I understand that it happens because I filter the Apps nodes in the first Match query. So I tried to do something like this to find all the Apps data related to affected Devices in a query:

WITH ["000001", "000002"] as IDS
UNWIND IDS as app_ids
MATCH (d:Device)-[:DEV_APP]->(a:Apps {app_id: app_ids})
WITH COLLECT(d) as device, COLLECT(distinct a) as app, COLLECT(distinct d.device_id) as device_ids
MATCH (d_all:Device {device_id: device_ids})-[:DEV_APP]->(a_all:Apps)
WITH device[1] as first, device[7] as second, app, COLLECT(a_all) as apps
WITH first.device_id AS id1, second.device_id as id2, application, apps
MATCH path=allShortestPaths((d1:Device {device_id:id1})-[:DEV_COL1|DEV_COL2|:DEV_COL3*..5]->(d2:Device {device_id:id2}))
RETURN path, application, apps

The problem is I get no records as the result. Although, I checked that device_ids list of nodes is not empty. And when I run the parts of this query separately, the results are displayed normally. What could be the mistake in this query?


Solution

  • The problem is in the 4th line:

    MATCH (d_all:Device {device_id: device_ids})-[:DEV_APP]->(a_all:Apps)

    Specifically device_ids. This is a collection from the line before, but I'm guessing there is no :Device where the device_id is a list with all of those list elements in that specific order.

    My guess is you meant to match to devices with a device id in that list, and you can't do that with this approach.

    Here's one way to do what you want:

    ...
    MATCH (d_all:Device)-[:DEV_APP]->(a_all:Apps)
    WHERE d_all.device_id IN device_ids
    ...
    

    or alternately:

    ...
    UNWIND device_ids as device_id
    MATCH (d_all:Device {device_id:device_id)-[:DEV_APP]->(a_all:Apps)
    ...
    

    or if the collection of devices includes all the devices you want:

    ...
    // using plurals for variable names of lists
    WITH COLLECT(d) as devices, COLLECT(distinct a) as apps, COLLECT(distinct d.device_id) as device_ids
    UNWIND devices as device 
    MATCH (device)-[:DEV_APP]->(a_all:Apps)
    ...