Skip to content

21 Shortest Path Graph And API

JP Barbosa edited this page Apr 15, 2023 · 1 revision

Shortest Path

Graph

code ./packages/graph/src/shortestPath/queries/get.ts
export const get = `
  WITH
    $person1 AS person1,
    $person2 AS person2
  MATCH path = shortestPath((p1:Person {name: person1})-[*]-(p2:Person {name: person2}))
  RETURN path
`;
code ./packages/graph/src/shortestPath/queries/index.ts
export * from './get';
code ./packages/graph/src/shortestPath/index.ts
import { PathSegment, Session } from 'neo4j-driver';
import { Edge, Node } from 'vis-network/standalone';
import { GraphVisData } from '@neo4j-crud/shared';
import * as queries from './queries';

type GetShortestPathReturn = GraphVisData;

type GetShortestPathResults = {
  path: {
    segments: PathSegment[];
  };
};

export const shortestPath = (session: Session) => ({
  get: async (
    person1: string,
    person2: string
  ): Promise<GetShortestPathReturn> => {
    const result = await session.run<GetShortestPathResults>(queries.get, {
      person1,
      person2,
    });

    const nodes: Node[] = [];
    const edges: Edge[] = [];

    if (!result.records.length) {
      return {
        nodes,
        edges,
      };
    }

    const { segments } = result.records[0].get('path');

    segments.forEach((segment, index) => {
      const { start, relationship, end } = segment;

      nodes.push({
        label:
          start.labels[0] === 'Movie'
            ? start.properties.title
            : start.properties.name,
        id: start.identity.toString(),
        group: start.labels[0],
      });

      edges.push({
        label: relationship.type,
        id: relationship.identity.toString(),
        from: relationship.start.toString(),
        to: relationship.end.toString(),
      });

      if (index === segments.length - 1) {
        nodes.push({
          label:
            end.labels[0] === 'Movie'
              ? end.properties.title
              : end.properties.name,
          id: end.identity.toString(),
          group: end.labels[0],
        });
      }
    });

    return {
      nodes,
      edges,
    };
  },
});
code ./packages/graph/src/index.ts
...
export * from './shortestPath';

API

code ./packages/api/src/controllers/shortestPath.ts
import { NextFunction } from 'express';
import { AppResponse, GraphVisData } from '@neo4j-crud/shared';
import * as graph from '@neo4j-crud/graph';

export const shortestPathController = {
  get: async (req, res: AppResponse<GraphVisData>, next: NextFunction) => {
    try {
      const person1 = req.query.person1 as string;
      const person2 = req.query.person2 as string;
      const result = await graph
        .shortestPath(req.neo4jSession)
        .get(person1, person2);
      res.send(result);
    } catch (err) {
      next(err);
    }
  },
};
code ./packages/api/src/controllers/index.ts
...
export * from './shortestPath';
code ./packages/api/src/routes/shortestPath.ts
import { Router } from 'express';
import { shortestPathController } from '../controllers';

const router = Router();

router.get('/', shortestPathController.get);

export default router;
code ./packages/api/src/routes/index.ts
...
import shortestPathRouter from './shortestPath';

...
routers.use('/shortest-path', shortestPathRouter);

export default routers;

Test

open "http://localhost:3333/shortest-path?person1=Tom%20Hanks&person2=Tom%20Cruise"
{
  "nodes": [
    { "label": "Tom Hanks", "id": "242", "group": "Person" },
    { "label": "Joe Versus the Volcano", "id": "249", "group": "Movie" },
    { "label": "Meg Ryan", "id": "205", "group": "Person" },
    { "label": "Top Gun", "id": "199", "group": "Movie" },
    { "label": "Tom Cruise", "id": "186", "group": "Person" }
  ],
  "edges": [
    { "label": "ACTED_IN", "id": "282", "from": "242", "to": "249" },
    { "label": "ACTED_IN", "id": "283", "from": "205", "to": "249" },
    { "label": "ACTED_IN", "id": "46", "from": "205", "to": "199" },
    { "label": "ACTED_IN", "id": "41", "from": "186", "to": "199" }
  ]
}

Commit

git add .
git commit -m "Shortest Path Graph And API"