labels() (graph function)

Learn how to use the labels() function to retrieve, filter, and project label information for nodes and edges in graph queries.

Retrieves the labels associated with nodes or edges in a graph query. Use this function to filter graph elements by their labels or to include label information in query results.

Labels are defined in graph models and can be either static (fixed labels assigned to node or edge types) or dynamic (labels derived from data properties during graph construction).

Syntax

labels( element )

labels()

Parameters

NameTypeRequiredDescription
elementstring✔️A node or edge variable reference from a graph pattern. Omit this parameter when using labels() inside all(), any(), or map() graph functions with inner_nodes(). For more information, see Graph pattern notation.

Returns

Returns a dynamic array of strings containing the labels associated with the specified node or edge. Returns an empty array for elements without labels or when used with graphs created created with the make-graph operator.

When called without parameters inside all(), any(), or map() with inner_nodes(), returns the labels for each inner node or edge in the path.

Label types

The labels() function retrieves both static and dynamic labels defined in the graph model. For detailed information about static and dynamic labels, including when to use each type, see Labels in Graph models.

Examples

These examples use the sample graphs available on the help cluster in the Samples database. For more information about these datasets, see Graph sample datasets.

Example 1: Filter nodes by labels

This example demonstrates filtering nodes based on their labels using the Simple educational graph. The query finds all people who work at a specific company and filters by the “Person” label.

graph("Simple")
| graph-match (person)-[works_at]->(company)
    where labels(person) has "Person" 
          and company.name == "TechCorp"
    project employee_name = person.name, 
            employee_age = person.properties.age,
            employee_labels = labels(person)
employee_nameemployee_ageemployee_labels
Alice25[“Person”]
Bob30[“Person”]
Emma26[“Person”]

This query uses labels(person) has "Person" to filter only nodes with the “Person” label, ensuring we’re working with person entities rather than other node types in the graph.

Example 2: Project labels in results

This example shows how to include label information in query results when analyzing social network connections using the LDBC SNB Interactive dataset. The query finds people who like posts and projects their labels.

graph("LDBC_SNB_Interactive")
| graph-match (person)-[likes]->(post)-[has_creator]->(creator)
    where labels(person) has "PERSON" 
          and labels(post) has "POST"
          and labels(has_creator) has "HAS_CREATOR"
    project 
        person_name = person.firstName,
        creator_name = creator.firstName,
        person_labels = labels(person),
        post_labels = labels(post),
        edge_labels = labels(has_creator)
| take 5
person_namecreator_nameperson_labelspost_labelsedge_labels
AbdullahMahinda[“PERSON”][“POST”][“HAS_CREATOR”]
AbdullahMahinda[“PERSON”][“POST”][“HAS_CREATOR”]
AbdullahMahinda[“PERSON”][“POST”][“HAS_CREATOR”]
AbdullahMahinda[“PERSON”][“POST”][“HAS_CREATOR”]
KarlMahinda[“PERSON”][“POST”][“HAS_CREATOR”]

This query projects the labels using labels() for both nodes and edges, showing how labels help categorize different entity types in a complex social network.

Example 3: Filter by multiple label conditions

This example demonstrates using multiple label conditions to identify financial transaction patterns in the LDBC Financial dataset. The query finds accounts that transfer money to other accounts and filters by specific node and edge labels.

graph("LDBC_Financial")
| graph-match (account1)-[transfer]->(account2)
    where labels(account1) has "ACCOUNT" 
          and labels(account2) has "ACCOUNT"
          and labels(transfer) has "TRANSFER"
          and transfer.amount > 1000000
    project 
        from_account = account1.node_id,
        to_account = account2.node_id,
        amount = transfer.amount,
        source_labels = labels(account1),
        target_labels = labels(account2),
        edge_labels = labels(transfer)
| take 5
from_accountto_accountamountsource_labelstarget_labelsedge_labels
Account::56576470318842045Account::46527813650271453965602050,75[“ACCOUNT”][“ACCOUNT”][“TRANSFER”]
Account::56576470318842045Account::46747364132105765847542124,31[“ACCOUNT”][“ACCOUNT”][“TRANSFER”]
Account::4695847036463875613Account::419397715298881002798953,34[“ACCOUNT”][“ACCOUNT”][“TRANSFER”]
Account::40532396646334920Account::990791918021513981893602,99[“ACCOUNT”][“ACCOUNT”][“TRANSFER”]
Account::98797716825440579Account::46755808381407076113952004,86[“ACCOUNT”][“ACCOUNT”][“TRANSFER”]

This query chains multiple label conditions to ensure both nodes and edges have the correct types, which is essential for accurate pattern matching in financial networks.

Example 4: Use labels() with inner_nodes() and collection functions

This example demonstrates using labels() without parameters inside any() and map() functions combined with inner_nodes() when working with variable-length paths in the BloodHound Active Directory dataset. The query finds privilege escalation paths where at least one edge along the path has dangerous permission labels, and also filters based on the labels of intermediate nodes.

graph("BloodHound_AD")
| graph-match (user)-[path*1..3]->(target)
    where labels(user) has "User" 
          and labels(target) has "Group"
          and target.properties.admincount == true
          and any(path, labels() has_any ("GenericAll", "WriteDacl", "WriteOwner", "GenericWrite", "Owns"))
          and all(inner_nodes(path), labels() has_any ("User", "Group"))
    project 
        attacker = user.name,
        target_group = target.name,
        path_length = array_length(path),
        permission_chain = map(path, labels()),
        intermediate_node_labels = map(inner_nodes(path), labels())
| take 5
attackertarget_grouppath_lengthpermission_chainintermediate_node_labels
HACKERDA@PHANTOM.CORPADMINISTRATORS@PHANTOM.CORP2[[“MemberOf”], [“WriteOwner”]][[“Base”, “Group”]]
ROSHI@PHANTOM.CORPADMINISTRATORS@PHANTOM.CORP2[[“MemberOf”], [“WriteOwner”]][[“Base”, “Group”]]
FABIAN@PHANTOM.CORPADMINISTRATORS@PHANTOM.CORP2[[“MemberOf”], [“WriteOwner”]][[“Base”, “Group”]]
ANDY@PHANTOM.CORPADMINISTRATORS@PHANTOM.CORP2[[“MemberOf”], [“WriteOwner”]][[“Base”, “Group”]]
CHARLIE@PHANTOM.CORPADMINISTRATORS@PHANTOM.CORP2[[“MemberOf”], [“WriteOwner”]][[“Base”, “Group”]]

In this query, labels() is used in multiple ways:

  • With any(path, labels() has_any (...)) to check edge labels for dangerous permissions
  • With all(inner_nodes(path), labels() has_any (...)) to filter paths based on intermediate node labels
  • With map(path, labels()) to show the edge labels along each path
  • With map(inner_nodes(path), labels()) to display the labels of intermediate nodes in the path

This demonstrates how labels() works seamlessly with inner_nodes() to access both edge and node labels in variable-length paths.