Star

Created With

linkFinding Nodes

Neogma provides some basic functionality for matching, filtering, limiting and ordering nodes. For more complex find statements, one can use the driver for running a raw query.

Type Safety: When using TypeScript, the where parameters in all find methods are type-checked against your model's properties. Both property names and value types are validated at compile time. See Where Parameters for details.

linkFinding Many Nodes

1linkimport { Op } from 'neogma';

2link

3link/* --> finds Users Nodes and returns an array of Users Instances */

4linkconst users = await Users.findMany({

5link /* --> the where param for matching the Nodes */

6link where: {

7link /* --> the name property of the User Nodes must be 'John' and their id must be in: ('1', '2') */

8link name: 'John',

9link /* --> using the "in" Symbol from "Op" */

10link id: { [Op.in]: ['1', '2'] },

11link },

12link /* --> (optional) the limit of this query */

13link limit: 3,

14link /* --> (optional) the skip of this query */

15link skip: 3,

16link /* --> (optional) the order of this query, in this case by: age DESC, id ASC */

17link order: [['age', 'DESC'], ['id', 'ASC']],

18link /* --> (optional, default false) returns an array of the plain properties, instead of Instances */

19link plain: false,

20link /* --> (optional) throws NeogmaNotFoundError if no nodes are found (results length 0) */

21link throwIfNoneFound: true,

22link /* --> (optional) an existing session or transaction to use */

23link session: null,

24link});

25link

26linkconsole.log(users[0].bar()); // "The name of this user is: John"

27linkconsole.log(users[0].age, users[0].id); // 45 "2"

28linkconsole.log(users[1].age, users[1].id); // 45 "3"

29linkconsole.log(users[2].age, users[2].id); // 38 "1"

linkFinding a single Node

1link/* --> finds a User Node and returns a Users Instances */

2linkconst user = await Users.findOne({

3link /* --> the where param for matching the Node */

4link where: {

5link /* --> the name property of the User Node must be 'John' */

6link name: 'John',

7link },

8link /* --> (optional) the order of this query, in this case by: id ASC */

9link order: [['id', 'ASC']],

10link /* --> (optional, default false) returns the plain properties, instead of Instance */

11link plain: false,

12link /* --> (optional) throws NeogmaNotFoundError if the node is not found */

13link throwIfNotFound: true,

14link /* --> (optional) an existing session or transaction to use */

15link session: null,

16link});

17link

18linkconsole.log(user.bar()); // "The name of this user is: John"

19linkconsole.log(user.id, user.age); // "1" 38

linkFinding nodes and relationships via the Model static

The findRelationships static can find related nodes via an Alias.

1linkconst relationships = await Users.findRelationships({

2link /* --> the alias of the relationship, as provided in the Model definition */

3link alias: 'Orders',

4link /* --> (optional) where parameters for the query */

5link where: {

6link /* --> (optional) where parameters of the source node (i.e. User) */

7link source: {

8link id: '1'

9link },

10link /* --> (optional) where parameters of the target node (i.e. Order) */

11link target: {

12link id: '2'

13link },

14link /* --> (optional) where parameters of the relationship between the nodes */

15link relationship: {

16link rating: 4

17link },

18link },

19link /* --> (optional) the order of the results. The 'on' property specifies the entity context: 'source', 'target', or 'relationship' */

20link order: [

21link {

22link on: 'relationship',

23link property: 'rating',

24link direction: 'DESC',

25link },

26link {

27link on: 'target',

28link property: 'date',

29link direction: 'ASC',

30link }

31link ],

32link /* --> (optional) limits the query. It's useful when the purpose is to find whether a relationship exists */

33link limit: 1,

34link /* --> (optional) skips the specified number of records. Useful in combination with 'limit' for pagination */

35link skip: 10,

36link /* --> (optional) minimum hops for a variable length relationship */

37link minHops: 1,

38link /* --> (optional) maximum hops for a variable length relationship. The value Infinity can be used for no limit on the max hops */

39link maxHops: 1,

40link /* --> (optional) throws NeogmaNotFoundError if no relationships are found */

41link throwIfNoneFound: false,

42link /* --> (optional) an existing session or transaction to use */

43link session: null,

44link});

45link

46linkconsole.log(relationships[0]?.source.id); // '1'

47linkconsole.log(relationships[0]?.target.id); // '2'

48linkconsole.log(relationships[0]?.relationship.rating); // 4

linkFinding nodes and relationships via the Instance method

The findRelationships method can find related nodes via an Alias. It's a wrapper for the corresponding static, while using the Instance as the source node.

1link/* --> let "user" be a Users instance with a primary field: id = '1' */

2linkconst relationships = await user.findRelationships({

3link /* --> the alias of the relationship, as provided in the Model definition */

4link alias: 'Orders',

5link /* --> (optional) where parameters for the query */

6link where: {

7link /* --> (optional) where parameters of the target node (i.e. Order) */

8link target: {

9link id: '2'

10link },

11link /* --> (optional) where parameters of the relationship between the nodes */

12link relationship: {

13link rating: 4

14link },

15link },

16link /* --> (optional) the order of the results. Use 'on' to apply sorting to the 'source', 'target', or 'relationship' */

17link order: [

18link {

19link on: 'relationship',

20link property: 'rating',

21link direction: 'DESC',

22link },

23link {

24link on: 'target',

25link property: 'date',

26link direction: 'ASC',

27link }

28link ],

29link /* --> (optional) limits the query. It's useful when the purpose is to find whether a relationship exists */

30link limit: 1,

31link /* --> (optional) skips the specified number of records. Useful in combination with 'limit' for pagination */

32link skip: 10,

33link /* --> (optional) minimum hops for a variable length relationship */

34link minHops: 1,

35link /* --> (optional) maximum hops for a variable length relationship. The value Infinity can be used for no limit on the max hops */

36link maxHops: 1,

37link /* --> (optional) throws NeogmaNotFoundError if no relationships are found */

38link throwIfNoneFound: false,

39link /* --> (optional) an existing session or transaction to use */

40link session: null,

41link});

42link

43linkconsole.log(relationships[0]?.source.id); // '1'

44linkconsole.log(relationships[0]?.target.id); // '2'

45linkconsole.log(relationships[0]?.relationship.rating); // 4

linkEager Loading Relationships

Neogma supports eager loading of relationships to fetch nodes with their related nodes in a single query. This avoids the N+1 query problem where you would otherwise need to make additional queries for each relationship.

linkBasic Usage

Use the relationships parameter in findMany or findOne to specify which relationships to load:

1linkconst users = await Users.findMany({

2link where: { status: 'active' },

3link relationships: {

4link /* --> Load Orders using the 'Orders' alias defined in the model */

5link Orders: {}

6link }

7link});

8link

9link/* --> Each user now has Orders populated */

10linkconsole.log(users[0].Orders);

11link// [

12link// { node: OrderInstance, relationship: { rating: 5, ... } },

13link// { node: OrderInstance, relationship: { rating: 4, ... } }

14link// ]

You can filter the related nodes and relationships using the where parameter:

1linkconst users = await Users.findMany({

2link where: { id: '1' },

3link relationships: {

4link Orders: {

5link where: {

6link /* --> Filter by target node properties */

7link target: {

8link status: 'completed'

9link },

10link /* --> Filter by relationship properties */

11link relationship: {

12link rating: { [Op.gte]: 4 }

13link }

14link }

15link }

16link }

17link});

linkOrdering and Pagination

Each relationship level supports order, limit, and skip:

1linkconst users = await Users.findMany({

2link where: { id: '1' },

3link order: [['name', 'ASC']], /* --> Order root nodes */

4link limit: 10, /* --> Limit root nodes */

5link relationships: {

6link Orders: {

7link /* --> Order related nodes */

8link order: [

9link { on: 'target', property: 'createdAt', direction: 'DESC' },

10link { on: 'relationship', property: 'rating', direction: 'DESC' }

11link ],

12link /* --> Limit related nodes per parent */

13link limit: 5,

14link skip: 0

15link }

16link }

17link});

linkNested Relationships

You can load relationships of related nodes to arbitrary depth:

1linkconst users = await Users.findMany({

2link where: { id: '1' },

3link relationships: {

4link Orders: {

5link limit: 10,

6link relationships: {

7link /* --> Load Items for each Order */

8link Items: {

9link limit: 20,

10link relationships: {

11link /* --> Load Supplier for each Item */

12link Supplier: {}

13link }

14link }

15link }

16link }

17link }

18link});

19link

20link/* --> Access nested data */

21linkconst firstOrder = users[0].Orders[0];

22linkconsole.log(firstOrder.node.id); // Order id

23link

24linkconst firstItem = firstOrder.node.Items[0];

25linkconsole.log(firstItem.node.name); // Item name

26link

27linkconst supplier = firstItem.node.Supplier[0];

28linkconsole.log(supplier.node.companyName); // Supplier company name

linkMultiple Relationships

Load multiple relationships in a single query:

1linkconst users = await Users.findMany({

2link where: { status: 'active' },

3link relationships: {

4link /* --> Load Orders */

5link Orders: {

6link where: { target: { status: 'pending' } },

7link limit: 5

8link },

9link /* --> Also load Friends (another relationship alias) */

10link Friends: {

11link limit: 10

12link }

13link }

14link});

15link

16linkconsole.log(users[0].Orders); // Array of order relationships

17linkconsole.log(users[0].Friends); // Array of friend relationships

linkResult Structure

Each loaded relationship returns an array of objects containing:

1linkconst users = await Users.findMany({

2link relationships: { Orders: {} }

3link});

4link

5linkfor (const orderRel of users[0].Orders) {

6link console.log(orderRel.node); // Order instance

7link console.log(orderRel.node.id); // Access node properties

8link console.log(orderRel.relationship); // Relationship properties

9link console.log(orderRel.relationship.rating); // e.g., 5

10link}

linkType Safety

When using TypeScript, the relationships parameter is fully typed based on your model's relationship definitions:

1link/* --> TypeScript will autocomplete valid aliases */

2linkconst users = await Users.findMany({

3link relationships: {

4link Orders: {}, // valid - 'Orders' is a defined alias

5link // InvalidAlias: {} // TypeScript error - 'InvalidAlias' doesn't exist

6link }

7link});

8link

9link/* --> Nested relationships are also typed based on the target model */

10linkconst users = await Users.findMany({

11link relationships: {

12link Orders: {

13link relationships: {

14link Items: {}, // valid - 'Items' is defined on Orders model

15link }

16link }

17link }

18link});

linkPerformance Considerations

Eager loading uses CALL subqueries with COLLECT to efficiently fetch all data in a single database round-trip:

1linkMATCH (root:User)

2linkWHERE root.status = $status

3linkCALL {

4link WITH root

5link OPTIONAL MATCH (root)-[rel:CREATES]->(target:Order)

6link WHERE target.status = $orderStatus

7link ORDER BY target.createdAt DESC

8link LIMIT 5

9link RETURN COLLECT({ node: target, relationship: rel }) AS Orders

10link}

11linkRETURN root, Orders

This approach:

Finding NodesFinding Many NodesFinding a single NodeFinding nodes and relationships via the Model staticFinding nodes and relationships via the Instance methodEager Loading RelationshipsBasic UsageFiltering Related NodesOrdering and PaginationNested RelationshipsMultiple RelationshipsResult StructureType SafetyPerformance Considerations

Introduction Getting Started

Modelschevron_right

Sessions and Transactions

Query Builderchevron_right
Query Runnerchevron_right

Bind Parameters

Where Parameters