labels() (graph function in Preview)

Applies to: ✅ Azure Data Explorer

Note

This feature is currently in public preview. Functionality and syntax are subject to change before General Availability.

The labels() graph function retrieves the labels associated with nodes or edges in a graph. It can be used for both filtering elements based on their labels and for projecting label information in query results.

Labels are defined within 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). The labels() function accesses these predefined labels to enable efficient filtering and analysis of graph elements.

Note

This function is used with the graph-match and graph-shortest-paths operators.

Important

When the labels() function is used on a graph created with the make-graph operator (that is, a transient graph rather than a persistent graph model), it always returns an empty array (of dynamic data type) for all nodes and edges, because transient graphs don't have label metadata.

Syntax

labels([element])

Parameters

Name Type Required Description
element string The reference to a graph node or edge variable in a graph pattern. Don't pass any parameters when used inside all(), any(), and map() graph functions, with inner_nodes(). For more information, see Graph pattern notation.

Returns

Returns a dynamic array containing the labels associated with the specified node or edge. For nodes and edges without labels, returns an empty array.

When used inside all(), any(), or map() with inner_nodes(), call labels() without parameters to return the labels for all inner nodes or edges, respectively.

Label sources

Labels are defined in Graph models and can originate from two sources:

  • Static labels: Fixed labels assigned to specific node or edge types during graph model definition. These labels remain constant for all instances of a particular type.
  • Dynamic labels: Labels derived from data properties during graph construction. These labels can vary based on the actual data values and computed expressions.

The labels() function retrieves both static and dynamic labels that were associated with graph elements through the graph model schema and definition.

Examples

Filter nodes by labels

The following example shows how to use the labels() function to filter nodes based on their assigned labels. The example includes the full graph model definition to clarify how static and dynamic labels are assigned.

Graph model definition

.create-or-alter graph_model AppProcessGraph ```
{
  "Schema": {
    "Nodes": {
      "Application": {"AppName": "string", "Type": "string"},
      "Process": {"ProcessName": "string"}
    },
    "Edges": {
      "CONNECTS_TO": {}
    }
  },
  "Definition": {
    "Steps": [
      {
        "Kind": "AddNodes",
        "Query": "Applications | project AppId, AppName, Type, NodeLabels",
        "NodeIdColumn": "AppId",
        "Labels": ["Application"],
        "LabelsColumn": "NodeLabels"
      },
      {
        "Kind": "AddNodes",
        "Query": "Processes | project ProcId, ProcessName",
        "NodeIdColumn": "ProcId",
        "Labels": ["Process"]
      },
      {
        "Kind": "AddEdges",
        "Query": "AppConnections | project SourceAppId, TargetProcId",
        "SourceColumn": "SourceAppId",
        "TargetColumn": "TargetProcId",
        "Labels": ["CONNECTS_TO"]
      }
    ]
  }
}
```

Query example

graph('AppProcessGraph')
| graph-match cycles=none (app)-[e*1..3]->(process)
    where process.ProcessName contains "nginx" and labels(app) has "Application"
    project app=app.AppName
| summarize c=count() by app
| top 10 by c desc

Output

app c
WebApp1 15
WebApp2 12
APIService 8

Project labels in results

The following example demonstrates how to use the labels() function in the project clause to include label information in the query results. This query finds connections between different types of network components and includes their labels for analysis.

Graph model definition

.create-or-alter graph_model NetworkGraph ```
{
  "Schema": {
    "Nodes": {
      "NetworkComponent": {"ComponentName": "string", "ComponentType": "string"}
    },
    "Edges": {
      "CONNECTED_TO": {"ConnectionType": "string"}
    }
  },
  "Definition": {
    "Steps": [
      {
        "Kind": "AddNodes",
        "Query": "NetworkComponentsTable | project Id, ComponentName, ComponentType, NodeLabels",
        "NodeIdColumn": "Id",
        "Labels": ["NetworkComponent"],
        "LabelsColumn": "NodeLabels"
      },
      {
        "Kind": "AddEdges",
        "Query": "ConnectionsTable | project SourceId, TargetId, ConnectionType, EdgeLabels",
        "SourceColumn": "SourceId",
        "TargetColumn": "TargetId",
        "Labels": ["CONNECTED_TO"],
        "LabelsColumn": "EdgeLabels"
      }
    ]
  }
}
```

Query example

graph('NetworkGraph')
| graph-match (source)-[conn]->(target)
    where labels(source) has "Network" and labels(target) has "Compute"
    project 
        SourceComponent = source.ComponentName,
        TargetComponent = target.ComponentName,
        SourceLabels = labels(source),
        TargetLabels = labels(target),
        ConnectionType = conn.ConnectionType

Output

SourceComponent TargetComponent SourceLabels TargetLabels ConnectionType
Switch1 Server1 ["Network", "Access"] ["Compute", "Production"] Ethernet

Filter by multiple label conditions

The following example shows how to combine multiple label conditions to find complex patterns in a network topology. This query identifies paths from frontend components to backend components through middleware layers.

Graph model definition

.create-or-alter graph_model AppComponentGraph ```
{
  "Schema": {
    "Nodes": {
      "Frontend": {"ComponentName": "string"},
      "Middleware": {"ComponentName": "string"},
      "Backend": {"ComponentName": "string"}
    },
    "Edges": {
      "DEPENDS_ON": {"DependencyType": "string"}
    }
  },
  "Definition": {
    "Steps": [
      {
        "Kind": "AddNodes",
        "Query": "ComponentsTable | project Id, ComponentName, NodeLabels",
        "NodeIdColumn": "Id",
        "LabelsColumn": "NodeLabels"
      },
      {
        "Kind": "AddEdges",
        "Query": "DependenciesTable | project SourceId, TargetId, DependencyType, EdgeLabels",
        "SourceColumn": "SourceId",
        "TargetColumn": "TargetId",
        "Labels": ["DEPENDS_ON"],
        "LabelsColumn": "EdgeLabels"
      }
    ]
  }
}
```

Query example

graph('AppComponentGraph')
| graph-match (frontend)-[dep1]->(middleware)-[dep2]->(backend)
    where labels(frontend) has "Frontend" 
          and labels(middleware) has "Middleware" 
          and labels(backend) has "Backend"
    project 
        Path = strcat(frontend.ComponentName, " -> ", middleware.ComponentName, " -> ", backend.ComponentName),
        FrontendLabels = labels(frontend),
        MiddlewareLabels = labels(middleware),
        BackendLabels = labels(backend)

Output

Path FrontendLabels MiddlewareLabels BackendLabels
WebUI -> APIGateway -> Database ["Frontend", "UserInterface"] ["Middleware", "API"] ["Backend", "Storage"]
WebUI -> APIGateway -> Cache ["Frontend", "UserInterface"] ["Middleware", "API"] ["Backend", "Cache"]

Use labels() with all() and any() functions

The following example demonstrates how to use the labels() function without parameters inside all() and any() functions with variable-length paths. This query finds paths in a service mesh where all intermediate services have "Production" labels and at least one intermediate service has "Critical" labels.

Graph model definition

.create-or-alter graph_model ServiceMeshGraph ```
{
  "Schema": {
    "Nodes": {
      "Service": {"ServiceName": "string", "Environment": "string"}
    },
    "Edges": {
      "CALLS": {"Protocol": "string"}
    }
  },
  "Definition": {
    "Steps": [
      {
        "Kind": "AddNodes",
        "Query": "ServicesTable | project Id, ServiceName, Environment, NodeLabels",
        "NodeIdColumn": "Id",
        "Labels": ["Service"],
        "LabelsColumn": "NodeLabels"
      },
      {
        "Kind": "AddEdges",
        "Query": "ServiceCallsTable | project SourceId, TargetId, Protocol, EdgeLabels",
        "SourceColumn": "SourceId",
        "TargetColumn": "TargetId",
        "Labels": ["CALLS"],
        "LabelsColumn": "EdgeLabels"
      }
    ]
  }
}
```

Query example

graph('ServiceMeshGraph')
| graph-match (source)-[calls*2..4]->(destination)
    where source.ServiceName == "UserService" and
          destination.ServiceName == "DatabaseService" and
          all(inner_nodes(calls), labels() has "Production") and
          any(inner_nodes(calls), labels() has "Critical")
    project 
        Path = strcat_array(map(inner_nodes(calls), ServiceName), " -> "),
        IntermediateLabels = map(inner_nodes(calls), labels()),
        CallProtocols = map(calls, Protocol)

Output

Path IntermediateLabels CallProtocols
AuthService -> PaymentService [["Production", "Auth"], ["Production", "Critical", "Payment"]] ["HTTPS", "gRPC"]
CacheService -> PaymentService [["Production", "Cache"], ["Production", "Critical", "Payment"]] ["Redis", "gRPC"]