People Graph
Default Return
code ./packages/graph/src/people/queries/_return.ts
export const _return = `
RETURN DISTINCT person {
.*,
id: id(person),
movies: [ (person)-[r]->(movie:Movie) | movie { .*, id: id(movie), relationship: type(r) } ]
}
`;
Get All
code ./packages/graph/src/people/queries/getAll.ts
import { _return } from './_return';
export const getAll = `
WITH toLower($search) AS search
MATCH (person:Person)
OPTIONAL MATCH (person)-[r]->(movie:Movie)
WITH *
WHERE
search IS NULL
OR search = ""
OR toLower(movie.title) CONTAINS search
OR toLower(person.name) CONTAINS search
WITH person
${_return}
ORDER BY person.name
`;
Get By ID
code ./packages/graph/src/people/queries/getById.ts
import { _return } from './_return';
export const getById = `
MATCH (person:Person)
WHERE id(person) = $id
${_return}
`;
Create
code ./packages/graph/src/people/queries/create.ts
import { _return } from './_return';
export const create = `
CREATE (person:Person)
SET
person.name = $person.name,
person.born = $person.born
${_return}
`;
Update
code ./packages/graph/src/people/queries/update.ts
import { _return } from './_return';
export const update = `
MATCH (person:Person)
WHERE id(person) = $id
SET
person.name = $person.name,
person.born = $person.born
${_return}
`;
Remove
code ./packages/graph/src/people/queries/remove.ts
export const remove = `
MATCH (person:Person)
WHERE id(person) = $id
DETACH DELETE person
`;
Index
code ./packages/graph/src/people/queries/index.ts
export * from './getAll';
export * from './getById';
export * from './create';
export * from './update';
export * from './remove';
Methods
code ./packages/graph/src/people/index.ts
import { Session } from 'neo4j-driver';
import { PeopleQueryResult, Person } from '@neo4j-crud/shared';
import * as queries from './queries';
export const people = (session: Session) => ({
getAll: async (search = '') => {
const result = await session.run<PeopleQueryResult>(queries.getAll, {
search,
});
const records = result.records.map((record) => record.get('person'));
return records;
},
getById: async (id: number) => {
const result = await session.run<PeopleQueryResult>(queries.getById, {
id,
});
const records = result.records.map((record) => record.get('person'));
return records.pop();
},
update: async (id: number, person: Person) => {
const result = await session.run<PeopleQueryResult>(queries.update, {
id,
person,
});
const records = result.records.map((record) => record.get('person'));
return records.pop();
},
create: async (person: Person) => {
const result = await session.run<PeopleQueryResult>(queries.create, {
person,
});
const records = result.records.map((record) => record.get('person'));
return records.pop();
},
remove: async (id: number) => {
const result = await session.run<PeopleQueryResult>(queries.remove, {
id,
});
const records = result.records.map((record) => record.get('person'));
return records.pop();
},
});
code ./packages/graph/src/index.ts
...
export * from './people';
Test
code ./packages/graph/src/people/index.spec.ts
import { Driver, Session } from 'neo4j-driver';
import { Person, people as samplePeople } from '@neo4j-crud/shared';
import * as graph from './';
import { neo4jDriver } from '../utils/neo4jDriver';
import {
neo4jConfigFile,
Neo4jContainerConfig,
} from '../utils/neo4jConfigFile';
import { ignoreId } from '../utils/ignoreId';
export const expectPeopleToBeEqual = (person1: Person, person2: Person) => {
const person1Parsed = ignoreId(person1);
const person2Parsed = ignoreId(person2);
expect(person1Parsed.name).toEqual(person2Parsed.name);
expect(person1Parsed.born).toEqual(person2Parsed.born);
};
describe('graph.people', () => {
jest.setTimeout(180_000);
let neo4jConfig: Neo4jContainerConfig;
let driver: Driver;
let session: Session;
const samplePerson = samplePeople[0];
const clearDatabase = async () => {
await session.run('MATCH (n) DETACH DELETE n');
};
beforeAll(async () => {
neo4jConfig = await neo4jConfigFile().read();
driver = await neo4jDriver(neo4jConfig);
session = driver.session();
await clearDatabase();
});
afterAll(async () => {
await session.close();
await driver.close();
//await container.stop();
});
it('should create a person', async () => {
const person = await graph.people(session).create(samplePerson);
expectPeopleToBeEqual(person, samplePerson);
});
it('should get the previously created person', async () => {
const [person] = await graph.people(session).getAll(samplePerson.name);
expectPeopleToBeEqual(person, samplePerson);
});
it('should update person tagline', async () => {
const [person] = await graph.people(session).getAll(samplePerson.name);
person.name += ' updated';
const updatedPerson = await graph.people(session).update(person.id, person);
expectPeopleToBeEqual(updatedPerson, person);
});
it('should delete the person', async () => {
const [person] = await graph.people(session).getAll(samplePerson.name);
await graph.people(session).remove(person.id);
const people = await graph.people(session).getAll(samplePerson.name);
expect(people).toHaveLength(0);
});
});
nx test graph
Determining test suites to run...
Neo4j container found at localhost:32768
PASS graph packages/graph/src/people/index.spec.ts
PASS graph packages/graph/src/movies/index.spec.ts
Test Suites: 2 passed, 2 total
Tests: 8 passed, 8 total
Snapshots: 0 total
Time: 2.892 s, estimated 3 s
Ran all test suites.
Commit
git add .
git commit -m "People Graph"