Skip to content

Recognized Where-Expressions

Gremlinq analyses the expression tree passed to .Where(...) and emits the corresponding Gremlin step — has(...), and(...), or(...), or where(...). Only the patterns listed here are recognised; anything else throws at runtime.

Basic predicates

Equality and inequality (==, !=)

Match vertices or edges by an exact property value. Works for strings, enums, numbers, and other comparable types.

C#
_g.V<Airport>().Where(a => a.Code == "JFK");

_g.V<Airport>().Where(a => a.Code != "JFK");

_g.V<Airport>().Where(a => a.Status == AirportStatus.Open);

_g.V<Airport>().Where(a => a.Status != AirportStatus.Closed);
Relational comparisons (>, >=, <, <=)

Compare a numeric property against a constant or variable. Works on int, long, and any type implementing IComparable<T>.

C#
_g.V<Airport>().Where(a => a.Elevation > 1000);

_g.V<Airport>().Where(a => a.Elevation >= 1000);

_g.V<Airport>().Where(a => a.Elevation < 500);

_g.V<Airport>().Where(a => a.Elevation <= 500);

_g.V<Airport>().OutE<Route>().Where(r => r.Distance >= 3000);
Null checks

Test whether a nullable property is present or absent in the graph.

C#
_g.V<Airport>().Where(a => a.City == null);

_g.V<Airport>().Where(a => a.ICAO != null);
Boolean properties

A bool property can be used directly as the predicate, or compared explicitly. Both forms translate to the same server-side filter.

C#
_g.V<AirportWithLounge>().Where(a => a.HasLounge);

_g.V<AirportWithLounge>().Where(a => !a.HasLounge);

_g.V<AirportWithLounge>().Where(a => a.HasLounge == true);

_g.V<AirportWithLounge>().Where(a => a.HasLounge == false);

Combining predicates

AND (&&)

All conditions must hold. Gremlinq emits a single and(...) step on the server.

C#
_g.V<Airport>().Where(a => a.Country == "US" && a.Elevation > 1000);

_g.V<Airport>().Where(a =>
    a.Country == "US" && a.Status == AirportStatus.Open && a.Elevation > 500);
OR (||)

At least one condition must hold. Gremlinq emits an or(...) step.

C#
_g.V<Airport>().Where(a =>
    a.Status == AirportStatus.Open || a.Status == AirportStatus.Limited);

_g.V<Airport>().Where(a => a.Country == "US" || a.Country == "CA");
Mixed AND / OR

Parenthesise sub-expressions to control precedence.

C#
_g.V<Airport>().Where(a =>
    a.Country == "US" && (a.Status == AirportStatus.Open || a.Elevation > 5000));

_g.V<Airport>().Where(a =>
    a.City == null && (a.Status == AirportStatus.Open || a.Status == AirportStatus.Limited));

Collection predicates

Value in collection (Contains)

Check whether a property value is a member of an in-memory collection. Negation is supported.

C#
_g.V<Airport>().Where(a => new[] { "JFK", "LHR", "CDG" }.Contains(a.Code));

_g.V<Airport>().Where(a => hubs.Contains(a.Code));

_g.V<Airport>().Where(a => !hubs.Contains(a.Code));
Array property predicates

When a vertex property is itself a collection, you can test membership, emptiness, and length. These examples use AirportWithAlternateCodes, an airport type with a string[]? AlternateCodes property.

C#
_g.V<AirportWithAlternateCodes>()
    .Where(a => a.AlternateCodes!.Contains("KNYC"));

_g.V<AirportWithAlternateCodes>()
    .Where(a => !a.AlternateCodes!.Contains("KNYC"));

_g.V<AirportWithAlternateCodes>()
    .Where(a => a.AlternateCodes!.Any());

_g.V<AirportWithAlternateCodes>()
    .Where(a => !a.AlternateCodes!.Any());

_g.V<AirportWithAlternateCodes>()
    .Where(a => a.AlternateCodes!.Length == 2);
Set intersection (.Intersect().Any())

Check whether an array property and a constant collection share at least one element.

C#
_g.V<AirportWithAlternateCodes>()
    .Where(a => a.AlternateCodes!.Intersect(new[] { "KNYC", "KJFK" }).Any());

_g.V<AirportWithAlternateCodes>()
    .Where(a => !a.AlternateCodes!.Intersect(new[] { "KNYC", "KJFK" }).Any());

String predicates

Prefix, suffix, and substring matching

StartsWith, EndsWith, Contains, and Equals all accept an optional StringComparison for case-insensitive matching.

C#
_g.V<Airport>().Where(a => a.Country!.StartsWith("United"));

_g.V<Airport>().Where(a =>
    a.Country!.StartsWith("united", StringComparison.OrdinalIgnoreCase));

_g.V<Airport>().Where(a => a.ICAO!.EndsWith("JFK"));

_g.V<Airport>().Where(a =>
    a.ICAO!.EndsWith("jfk", StringComparison.OrdinalIgnoreCase));

_g.V<Airport>().Where(a => a.City!.Contains("York"));

_g.V<Airport>().Where(a =>
    a.City!.Contains("york", StringComparison.OrdinalIgnoreCase));

_g.V<Airport>().Where(a =>
    a.Country!.Equals("US", StringComparison.OrdinalIgnoreCase));
Reversed matching — constant on the left

When the constant string is on the left and the property is the argument, Gremlinq inverts the predicate direction. Use this to express "is the property value a prefix/substring of a known identifier?"

C#
_g.V<Airport>().Where(a => "JFK-Gate-4".StartsWith(a.Code!));

_g.V<Airport>().Where(a => "JFK-Gate-4".Contains(a.Code!));
Lexicographic ordering (CompareTo)

All six comparison operators (==, !=, <, <=, >, >=) can be used against the return value of CompareTo.

C#
_g.V<Airport>().Where(a => a.Code!.CompareTo("JFK") == 0);

_g.V<Airport>().Where(a => a.Code!.CompareTo("JFK") < 0);   // alphabetically before JFK

_g.V<Airport>().Where(a => a.Code!.CompareTo("JFK") >= 0);  // JFK and later

Advanced predicates

Property-to-property comparisons

Compare two properties on the same element directly.

C#
_g.V<Airport>().Where(a => a.Code == a.ICAO);

_g.V<Airport>().Where(a => a.City == a.Country);
Id access and casts

The Id property (type object?) can be compared after an explicit cast, or the right-hand side can be cast to object.

C#
_g.V<Airport>().Where(a => a.Id == (object)"airport-1");

_g.V<Airport>().Where(a => (string?)a.Id == "airport-1");
Custom value types (Vogen, DateOnly, …)

Any type that Gremlinq knows how to serialise works in comparisons. This example uses the OpenedDate Vogen value object.

C#
_g.V<Airport>().Where(a =>
    a.OpenedDate == OpenedDate.From(new DateOnly(1960, 1, 1)));

_g.V<Airport>().Where(a => a.OpenedDate >= cutoff);
Captured variables and closures

Variables, parameters, and computed expressions from the enclosing scope are evaluated client-side and sent as constants in the Gremlin query.

C#
_g.V<Airport>().Where(a => a.Elevation > minElevation + bonus);

_g.V<Airport>().Where(a => a.Country == filter.Country);
Step label references

After capturing a vertex with .As(...), its property values can be referenced inside a downstream Where. This example finds airports reachable from any origin that share the same country.

C#
_g
    .V<Airport>()
    .As((__, origin) => __
        .Out<Route>()
        .OfType<Airport>()
        .Where(a => a.Country == origin.Value.Country));

See Step Labels for the full step-label API.

Sub-traversal predicates

Pass a traversal lambda instead of a property lambda to filter by structural graph conditions rather than property values. The filter passes if the sub-traversal yields at least one result.

Keep an element only if it has outbound or inbound routes:

C#
_g.V<Airport>().Where(_ => _.Out<Route>());

_g.V<Airport>().Where(_ => _.In<Route>());

Sub-traversals can contain their own Where — useful when the condition involves a hop:

C#
_g.V<Airport>().Where(__ => __
    .Out<Route>()
    .OfType<Airport>()
    .Where(a => a.Country == "US"));

Assert that a property has a value in the graph (useful for sparse properties):

C#
_g.V<Airport>().Where(a => a.Values(x => x.City));
VertexProperty metadata

When filtering on VertexProperty elements returned by .Properties(...), you can test the property's value or key.

C#
_g
    .V<AirportWithNotes>()
    .Properties(a => a.Note!)
    .Where(vp => vp.Value == "Hub airport, 24h operations");

_g
    .V<AirportWithNotes>()
    .Properties(a => a.Note!)
    .Where(vp => vp.Key == "Note");
Projected tuple element access

After a .Project().ToTuple().By(...) projection, Where can filter on individual tuple elements via .Item1, .Item2, etc. This example retains only airports with more than five outbound routes.

C#
_g
    .V<Airport>()
    .Project(__ => __
        .ToTuple()
        .By(__ => __.Identity())
        .By(__ => __.Out<Route>().Fold()))
    .Where(x => x.Item2.Length > 5);

Related: Step Labels — typed handles for intermediate traversal results used in label-value comparisons  |  Vertex PropertiesVertexProperty<TValue> and meta-property access.