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.
Relational comparisons (>, >=, <, <=)
Compare a numeric property against a constant or variable. Works on int, long, and any type implementing IComparable<T>.
Null checks
Test whether a nullable property is present or absent in the graph.
Boolean properties
A bool property can be used directly as the predicate, or compared explicitly. Both forms translate to the same server-side filter.
Combining predicates
AND (&&)
All conditions must hold. Gremlinq emits a single and(...) step on the server.
OR (||)
At least one condition must hold. Gremlinq emits an or(...) step.
Mixed AND / OR
Parenthesise sub-expressions to control precedence.
Collection predicates
Value in collection (Contains)
Check whether a property value is a member of an in-memory collection. Negation is supported.
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.
_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.
String predicates
Prefix, suffix, and substring matching
StartsWith, EndsWith, Contains, and Equals all accept an optional StringComparison for case-insensitive matching.
_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?"
Lexicographic ordering (CompareTo)
All six comparison operators (==, !=, <, <=, >, >=) can be used against the return value of CompareTo.
Advanced predicates
Property-to-property comparisons
Compare two properties on the same element directly.
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.
Custom value types (Vogen, DateOnly, …)
Any type that Gremlinq knows how to serialise works in comparisons. This example uses the OpenedDate Vogen value object.
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.
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.
_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:
Sub-traversals can contain their own Where — useful when the condition involves a hop:
Assert that a property has a value in the graph (useful for sparse properties):
VertexProperty metadata
When filtering on VertexProperty elements returned by .Properties(...), you can test the property's value or key.
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.
Related: Step Labels — typed handles for intermediate traversal results used in label-value comparisons |
Vertex Properties — VertexProperty<TValue> and meta-property access.