Filters Use WHERE operators, logical groups, related-table filters, JSON operators, and geo filters. core reference core/filters core/filters.md

Filters

Use WHERE operators, logical groups, related-table filters, JSON operators, and geo filters.

Filter shape

GraphJin filters live inside an inline where object. Keep the object shape in the query and use variables as leaf values:

GraphQL
query Products($min: Float!, $max: Float!, $ids: [Int!]) {
  products(
    where: {
      price: { gte: $min, lte: $max }
      id: { in: $ids }
    }
    order_by: { id: asc }
  ) {
    id
    name
    price
  }
}
JSON
{ "min": 10, "max": 100, "ids": [1, 2, 3] }

Do not pass the entire filter as where: $where. Whole-object filters are rejected so saved queries and allow-list review keep a stable operation shape.

Scalar and list operators

FamilyOperatorsNotes
Equalityeq, neqUse real booleans/numbers, not strings like "true" or "50".
Ordered comparisonsgt, gte, lt, lteAliases such as lteq, lesser_or_equals, and greater_or_equals are covered by tests.
Listsin, ninValues must be arrays, even for one value.
Nullsis_nullUse true for null checks and combine with not for not-null checks.
Textlike, ilike, regex, iregex, similarPattern semantics are dialect-specific; ilike needs % wildcards for partial matches.
GraphQL
query {
  products(
    where: { price: { gt: 10, lt: 100 } }
    order_by: { id: asc }
    limit: 3
  ) {
    id
    name
    price
  }
}

Common operators include eq, neq, gt, gte, lt, lte, in, nin, is_null, and iregex.

Verified by Example_queryWithWhereGreaterThanOrLesserThan tests/query_test.go:471
Verified by Example_queryWithWhereIn tests/query_test.go:411

Logical groups

and, or, and not can wrap column filters, relationship filters, and spatial filters.

GraphQL
query {
  products(where: {
    and: [
      { not: { id: { is_null: true } } },
      { price: { gt: 10 } }
    ]
  }) {
    id
  }
}
Verified by Example_queryWithWhereNotIsNullAndGreaterThan tests/query_test.go:438

Text search filters

GraphQL
query Products($name: String!) {
  products(
    where: {
      id: [3, 34]
      or: {
        name: { iregex: $name }
        description: { iregex: $name }
      }
    }
    order_by: { id: asc }
  ) {
    id
  }
}
JSON
{ "name": "Product 3" }

The id: [3, 34] shorthand is useful for primary-key lists, while the explicit operator form is clearer when the filter will be reused in saved queries.

Verified by Example_queryWithWhere1 tests/query_test.go:377
GraphQL
query ($user_id: ID!) {
  products(
    where: { owner: { id: { or: [{ eq: $user_id }, { eq: 3 }] } } }
    order_by: { id: asc }
    limit: 2
  ) {
    id
    owner { email }
  }
}
Verified by Example_queryWithWhereOnRelatedTable tests/query_test.go:504

Relationship filters compile through the same schema relationship graph as nested selections. Do not guess relationship names in agentic workflows; search gj_catalog for relationship rows first.

JSON filters and path fields

JSON columns can use key operators and path-derived fields.

GraphQL
query {
  products(
    where: { metadata: { has_key_any: ["foo", "bar"] } }
    order_by: { id: asc }
    limit: 3
  ) {
    id
  }
}
GraphQL
query {
  products(
    where: { metadata_foo: { eq: true } }
    order_by: { id: asc }
    limit: 10
  ) {
    id
    metadata_foo
  }
}

Underscore notation maps to JSON path access for supported JSON columns. Key operators include has_key, has_key_any, has_key_all, contains, and contained_in.

Verified by Example_queryJSONPathOperations tests/query_test.go:96
Verified by Example_queryJSONPathOperationsAlternativeSyntax tests/query_test.go:129
Verified by Example_queryWithWhereHasAnyKey tests/query_test.go:2007

Geo filters

Spatial filters are available when the dialect and deployment support spatial types. The shared examples cover PostGIS, MySQL 8+, MariaDB, SQLite with SpatiaLite, SQL Server, Oracle Spatial, and MongoDB where the operation maps cleanly.

Distance

GraphQL
query {
  locations(
    where: {
      geom: {
        st_dwithin: {
          point: [-122.4, 37.8]
          distance: 10000
        }
      }
    }
    order_by: { id: asc }
  ) {
    id
    name
  }
}
Verified by Example_queryWithGeoFilter tests/geo_test.go:10

Distance can include units and variables:

GraphQL
query Nearby($loc: JSON!, $radius: Float!) {
  locations(where: {
    geom: { st_dwithin: { point: $loc, distance: $radius } }
  }) {
    id
    name
  }
}
GraphQL
query {
  locations(where: {
    geom: { st_dwithin: { point: [-122.4194, 37.7749], distance: 5, unit: "miles" } }
  }) {
    id
    name
  }
}

Verified by TestGeoStDWithinVariable core/internal/qcode/geo_test.go:63
Verified by TestGeoStDWithinWithUnit core/internal/qcode/geo_test.go:42

Shape relationships

GraphQL
query {
  locations(where: {
    geom: {
      st_within: {
        polygon: [[-122.5, 37.7], [-122.3, 37.7], [-122.3, 37.9], [-122.5, 37.9], [-122.5, 37.7]]
      }
    }
  }) {
    id
  }
}
GraphQL
query {
  parcels(where: {
    geom: {
      st_intersects: {
        geometry: {
          type: "Polygon"
          coordinates: [[[-122.5, 37.7], [-122.3, 37.7], [-122.3, 37.9], [-122.5, 37.9], [-122.5, 37.7]]]
        }
      }
    }
  }) {
    id
  }
}

Supported spatial operator names include st_within, st_contains, st_intersects, st_coveredby, st_covers, st_touches, and st_overlaps.

Verified by Example_queryWithGeoContains tests/geo_test.go:46
Verified by TestGeoStIntersectsGeoJSON core/internal/qcode/geo_test.go:133
Verified by TestGeoStTouches core/internal/qcode/geo_test.go:198
Verified by TestGeoStOverlaps core/internal/qcode/geo_test.go:219
Verified by TestGeoStCoveredBy core/internal/qcode/geo_test.go:242
Verified by TestGeoStCovers core/internal/qcode/geo_test.go:265

MongoDB near

GraphQL
query {
  locations(where: {
    geom: { near: { point: [-122.4194, 37.7749], maxDistance: 5000 } }
  }) {
    id
    name
  }
}
Verified by TestGeoNear core/internal/qcode/geo_test.go:156

Wrong / Right examples

WrongRightWhy
where: $wherewhere: { label: { eq: $label } }Whole-object filters break saved-query review and are rejected.
where: { id: { in: 1 } }where: { id: { in: [1] } }in and nin require arrays.
where: { price: { gt: "50" } }where: { price: { gt: 50 } }Numeric operators need numeric values.
where: { active: { eq: "true" } }where: { active: { eq: true } }Boolean values are true and false.
where: { name: { ilike: "phone" } }where: { name: { ilike: "%phone%" } }SQL LIKE partial matching needs wildcards.

These same mistakes are exposed to AI clients through serv/mcp_syntax.go so MCP users receive the same guidance.

Docs