Complete guide to Prisma-style filtering, sorting, and pagination in SharpGraph.
All examples use the Star Wars GraphQL Database with 6 entity types: Character, Film, Planet, Species, Starship, and Vehicle.
- Connection Pattern
- Filtering with
where - Sorting with
orderBy - Pagination
- Combined Queries
- Filter Operators Reference
- Auto-Generated CRUD Mutations
- Examples
SharpGraph uses the GraphQL Connection pattern for advanced querying. Every list query returns a Connection object with an items field that supports filtering, sorting, and pagination.
Schema Structure:
# Connection type (auto-generated)
type CharacterConnection {
items(
where: CharacterWhereInput
orderBy: [CharacterOrderBy!]
skip: Int
take: Int
): [Character!]!
}
# Query field returns Connection
type Query {
characters: CharacterConnection!
}Query Structure:
query {
characters { # Returns CharacterConnection
items( # Access the items field with filters
where: {...} # Filter conditions
orderBy: [{...}] # Sort fields
skip: 0 # Pagination offset
take: 10 # Pagination limit
) {
id # Select fields from items
name
}
}
}The where argument accepts a filter object matching your entity's structure.
query {
characters {
items(where: {characterType: {equals: "Human"}}) {
id
name
characterType
}
}
}Available for String fields:
query {
characters {
items(where: {
name: {
contains: "Luke" # Contains substring
startsWith: "L" # Starts with
endsWith: "er" # Ends with
equals: "Luke Skywalker" # Exact match
}
}) {
id
name
}
}
}Available for Int and Float fields:
query {
characters {
items(where: {
height: {
equals: 172 # Exact match
gt: 170 # Greater than
gte: 170 # Greater than or equal
lt: 180 # Less than
lte: 180 # Less than or equal
}
}) {
id
name
height
}
}
}Available for Boolean fields:
query {
characters {
items(where: {
isActive: {
equals: true
}
}) {
id
name
}
}
}query {
characters {
items(where: {
AND: [
{characterType: {equals: "Human"}}
{height: {gte: 170}}
{name: {contains: "Luke"}}
]
}) {
id
name
characterType
height
}
}
}query {
characters {
items(where: {
OR: [
{characterType: {equals: "Droid"}}
{characterType: {equals: "Wookiee"}}
]
}) {
id
name
characterType
}
}
}query {
characters {
items(where: {
NOT: {
characterType: {equals: "Droid"}
}
}) {
id
name
characterType
}
}
}query {
characters {
items(where: {
AND: [
{
OR: [
{characterType: {equals: "Human"}}
{characterType: {equals: "Droid"}}
]
}
{height: {gt: 0}}
]
}) {
id
name
characterType
height
}
}
}SharpGraph uses Prisma-style sorting where each field maps directly to a sort direction.
Sort ascending (default ascending order):
query {
characters {
items(orderBy: [{name: asc}]) {
id
name
characterType
}
}
}Sort descending:
query {
characters {
items(orderBy: [{name: desc}]) {
id
name
characterType
}
}
}Sort by multiple fields in order (primary sort, then secondary, etc.):
query {
characters {
items(orderBy: [
{characterType: asc} # Primary sort
{name: asc} # Secondary sort
{height: desc} # Tertiary sort
]) {
id
name
characterType
height
}
}
}query {
characters {
items(orderBy: [
{characterType: asc} # Ascending
{height: desc} # Descending
]) {
id
name
characterType
height
}
}
}Use skip and take for pagination.
Get 10 items, skip first 20:
query {
characters {
items(skip: 20, take: 10) {
id
name
}
}
}query {
characters {
items(skip: 0, take: 10) {
id
name
}
}
}# Page 2
query {
characters {
items(skip: 10, take: 10) {
id
name
}
}
}
# Page 3
query {
characters {
items(skip: 20, take: 10) {
id
name
}
}
}For page-based pagination:
- Page 1:
skip: 0 - Page 2:
skip: 10 - Page 3:
skip: 20 - Page N:
skip: (N - 1) * pageSize
Combine filtering, sorting, and pagination for powerful queries.
query {
characters {
items(
where: {characterType: {equals: "Human"}}
orderBy: [{name: asc}]
) {
id
name
characterType
}
}
}query {
characters {
items(
where: {height: {gt: 170}}
orderBy: [{height: desc}]
skip: 0
take: 5
) {
id
name
height
}
}
}Get tall humans, sorted by name, paginated:
query GetTallHumans($pageSize: Int!, $page: Int!) {
characters {
items(
where: {
AND: [
{characterType: {equals: "Human"}}
{height: {gte: 180}}
]
}
orderBy: [{name: asc}]
skip: $pageSize * ($page - 1)
take: $pageSize
) {
id
name
characterType
height
mass
}
}
}Query with variables:
{
"pageSize": 10,
"page": 1
}| Operator | Description | Example |
|---|---|---|
equals |
Exact match | {name: {equals: "Luke"}} |
contains |
Contains substring (case-insensitive) | {name: {contains: "Luke"}} |
startsWith |
Starts with | {name: {startsWith: "L"}} |
endsWith |
Ends with | {name: {endsWith: "er"}} |
| Operator | Description | Example |
|---|---|---|
equals |
Exact value | {height: {equals: 172}} |
gt |
Greater than | {height: {gt: 170}} |
gte |
Greater than or equal | {height: {gte: 170}} |
lt |
Less than | {height: {lt: 180}} |
lte |
Less than or equal | {height: {lte: 180}} |
| Operator | Description | Example |
|---|---|---|
equals |
Match true/false | {isActive: {equals: true}} |
| Operator | Description | Example |
|---|---|---|
AND |
All conditions true | {AND: [{...}, {...}]} |
OR |
Any condition true | {OR: [{...}, {...}]} |
NOT |
Condition false | {NOT: {...}} |
| Value | Description |
|---|---|
asc |
Ascending order (default) |
desc |
Descending order |
SharpGraph automatically generates Create, Update, and Delete mutations for every entity.
Create a new record:
mutation CreateCharacter {
createCharacter(input: {
name: "Obi-Wan Kenobi"
characterType: "Human"
appearsIn: ["NEWHOPE", "EMPIRE", "JEDI"]
height: 182.88
hairColor: "Auburn, White"
eyeColor: "Blue-gray"
}) {
id
name
characterType
}
}Read with filtering:
query {
characters {
items(where: {name: {contains: "Kenobi"}}) {
id
name
characterType
height
}
}
}Or fetch specific record by ID:
query {
character(id: "luke") {
id
name
characterType
height
}
}Update a record:
mutation UpdateCharacter {
updateCharacter(
id: "luke"
input: {
height: 175.26
birthYear: "19BBY"
}
) {
id
name
height
birthYear
}
}Delete a record:
mutation DeleteCharacter {
deleteCharacter(id: "luke")
}Find all films from the original trilogy, sorted by episode:
query OriginalTrilogy {
films {
items(
where: {
episodeId: {
AND: [
{gte: 4}
{lte: 6}
]
}
}
orderBy: [{episodeId: asc}]
) {
id
title
episodeId
releaseDate
}
}
}Implement client-side pagination (10 items per page):
query CharactersPage($pageSize: Int!, $page: Int!) {
characters {
items(
orderBy: [{name: asc}]
skip: $pageSize * ($page - 1)
take: $pageSize
) {
id
name
characterType
}
}
}Complete create, read, update, delete workflow:
# 1. CREATE
mutation {
createSpecies(input: {
name: "Human"
classification: "Mammal"
designation: "Sentient"
averageHeight: "180"
language: "Galactic Basic"
}) {
id
name
}
}
# 2. READ
query {
allSpecies {
items(where: {name: {equals: "Human"}}) {
id
name
classification
}
}
}
# 3. UPDATE
mutation {
updateSpecies(
id: "1"
input: {
averageHeight: "180.34"
}
) {
id
averageHeight
}
}
# 4. DELETE
mutation {
deleteSpecies(id: "1")
}Find all non-droid characters taller than 170cm:
query {
characters {
items(
where: {
AND: [
{
NOT: {
characterType: {equals: "Droid"}
}
}
{height: {gt: 170}}
]
}
orderBy: [{height: desc}, {name: asc}]
take: 10
) {
id
name
characterType
height
}
}
}Need help? See README.md for more information or check examples/ for complete working examples.