Gelly Reference

Queries

Selecting Fields of Models

gelly
1query {
2 posts {
3 id
4 title
5 }
6}
json
1{
2 "posts": [
3 { "id": 1, "title": "Hello World" },
4 { "id": 2, "title": "Thoughts on Software Development" }
5 ]
6}
gelly
1query {
2 posts {
3 id
4 title
5 publishedDate
6 }
7 currentUser {
8 name
9 email
10 }
11}
json
1{
2 "posts": [{"id": 1, ...}, {"id": 2, ...}],
3 "currentUser": {
4 "name": "Jane McGee",
5 "email": "[email protected]"
6 }
7}

Selecting Relationships

gelly
1query {
2 posts {
3 id
4 title
5 comments {
6 id
7 commentBody
8 }
9 }
10}
json
1{
2 "posts": [
3 {
4 "id": 1,
5 "title": "Hello World",
6 "comments": [
7 {
8 "id": 1,
9 "commentBody": "Nice post!"
10 },
11 {
12 "id": 2,
13 "commentBody": "Cool blog!"
14 }
15 ]
16 }
17 ]
18}
gelly
1query {
2 posts {
3 id
4 title
5 comments {
6 id
7 commentBody
8 commentUpvotes {
9 id
10 createdAt
11 }
12 }
13 }
14}

Expressions

gelly
1query {
2 customers {
3 id
4 fullName: firstName + " " + lastName
5 }
6}
json
{
"customers": [{ "fullName": "Jane McGee" }, { "fullName": "Joe Schmoe" }]
}
gelly
query {
1
}

json
{
"1": 1
}
gelly
1query {
2 comments {
3 id
4 isSpam: author.markedAsSpammer || contains(lower(title), "spam") || author.spamScore < (endsWith(author.email, "@gmail.com") ? 10 : 5)
5 }
6}

Aliasing Fields and Expressions

gelly
query {
posts {
humanName: title
}
}
json
{
"posts": [{ "humanName": "Hello World!" }, { "humanName": "Thoughts on Software Development" }]
}
gelly
query {
posts {
screamingTitle: upcase(title)
}
}
json
{
"posts": [{ "screamingTitle": "HELLO WORLD!" }, { "humanName": "THOUGHTS ON SOFTWARE DEVELOPMENT" }]
}
gelly
query {
posts {
upcase(title)
}
}
json
{
"posts": [{ "upcase(title)": "HELLO WORLD!" }, { "upcase(title)": "THOUGHTS ON SOFTWARE DEVELOPMENT" }]
}

Commands

gelly
1query {
2 posts {
3 id
4 title
5 [limit 5]
6 }
7}
gelly
1query {
2 posts {
3 id
4 title
5 [where published]
6 }
7}
gelly
1query {
2 posts {
3 id
4 title
5 [where published && score > 10]
6 }
7}
gelly
1query {
2 posts {
3 id
4 title
5 comments {
6 id
7 body
8 [order by score desc limit 3]
9 }
10 }
11}
gelly
1query {
2 posts {
3 id
4 title
5 [where published limit 3 order by createdDate desc]
6
7 comments {
8 id
9 body
10 [order by score desc limit 3]
11 }
12 }
13}

The limit command

[limit <number>]
Limiting to a count
gelly
1query {
2 posts {
3 title
4 [limit 5]
5 }
6 }
Limiting at different nesting
gelly
1query {
2 posts {
3 title
4 [limit 5]
5 comments {
6 body
7 [limit 3]
8 }
9 }
10 }
Limiting at different nesting
gelly
1query {
2 posts {
3 title
4 score
5 [order by score desc limit 10]
6 }
7 }

The order by command

[order by <expression> <asc|desc>]
Ordering by a date field
gelly
1query {
2 posts {
3 title
4 [order by createdDate desc]
5 }
6 }
Ordering by an expression
gelly
1query {
2 posts {
3 title
4 [order by author.scoreWeight * post.score]
5 }
6 }

The where command

[where <expression>]
Positive score posts
gelly
1query {
2 posts {
3 title
4 [where score > 0]
5 }
6 }
Interesting posts
gelly
1query {
2 posts {
3 title
4 score
5 author.isSpam
6 [where (!author.isSpam && score > 50) || (author.isSpam && score > 100)]
7 }
8 }
Interesting posts
gelly
1query {
2 posts {
3 title
4 score
5 [where !author.isSpam order by score desc limit 10]
6 }
7 }

The group by command

[group by <expression> <, ...expression> <, ...expression>]
Post count by author
gelly
1query {
2 posts {
3 count(id)
4 authorId
5 [group by authorId]
6 }
7 }
Authors with count of posts
gelly
1query {
2 authors {
3 id
4 name
5 count(posts.id)
6 }
7 }
Post count by score bucket
gelly
1query {
2 posts {
3 count(id)
4 scoreBucket: score % 10
5 [group by scoreBucket]
6 }
7 }
Ordering aggregate results
gelly
1query {
2 posts {
3 postCount: count(id)
4 authorId
5 [group by authorId order by postCount desc]
6 }
7 }
Ham Post count by author
gelly
1query {
2 posts {
3 count(id)
4 authorId
5 [
6 group by authorId
7 where !isSpam
8 ]
9 }
10 }

All selected expressions must aggregate the input rows when grouped

Ungrouped fields cause errors
gelly
1query {
2 posts {
3 count(id)
4 # will cause an error because the field is not being aggregated
5 score
6 [group by authorId]
7 }
8 }

Fragments

gelly
1fragment PostDetails on Post {
2 id
3 title
4}
5
6query {
7 posts {
8 ...PostDetails
9 [where published]
10 }
11}
Fragments with relational commands
gelly
1fragment PublishedPostDetails on Post {
2 id
3 title
4 [where published]
5 }
6 query {
7 posts {
8 ...PostDetails
9 author {
10 id
11 }
12 [limit 10]
13 }
14 }

Fragment Variables

Fragments with variables
gelly
1fragment PostsForAuthor($authorId: ID!) on Post {
2 id
3 title
4 [where authorId = $authorId]
5 }
6 query {
7 posts {
8 ...PostsForAuthor(authorId: "123")
9 author {
10 id
11 }
12 [limit 10]
13 }
14 }
Fragments with variables
gelly
1fragment PostDetails($onlyInteresting: Boolean) on Post {
2 hotRightNow: $onlyInteresting ? score > 100 : false
3 [where $onlyInteresting ? score > 10 : true]
4 }
5 query($full: Boolean) {
6 posts {
7 id
8 title
9 ...PostDetails(onlyInteresting: $full)
10 [limit 10]
11 }
12 }
Fragments with variables
gelly
1# the $onlyInteresting variable won't be available in this fragment unless we declare it at the top of the fragment
2 fragment PostDetails($onlyInteresting: Boolean) on Post {
3 hotRightNow: $onlyInteresting ? score > 100 : false
4 [where $onlyInteresting ? score > 10 : true]
5 }
6 query($onlyInteresting: Boolean) {
7 posts {
8 id
9 title
10 # the $onlyInteresting variable must be passed into the fragment, even if it has the same name in the query context
11 ...PostDetails(onlyInteresting: $onlyInteresting)
12 [limit 10]
13 }
14 }

Field Fragments

isPopular field fragment
gelly
1# in the Gadget editor, in isPopular.gelly
2 field isPopular on Post {
3 score > 100
4 }
5 # in a Gelly query later
6 query {
7 posts {
8 title
9 isPopular
10 [limit 10]
11 }
12 }
popularPostCount field fragment
gelly
1# in the Gadget editor, in popularPostCount.gelly
2 field popularPostCount on Author {
3 count(posts, where: posts.score > 10)
4 }
5 # in a Gelly query later
6 query {
7 authors {
8 id
9 name
10 popularPostCount
11 [limit 10]
12 }
13 }

Built-in Data Types

Number literals
gelly
query {
anInteger: 5
aDecimal: 10.5
}
Boolean literals
gelly
query {
yes: true
no: false
}
String literals
gelly
query {
aString: "foo"
withAQuoteInIt: "when she said "yes", it was incredible!"
}
Date literals
gelly
query {
aTimestamp: timestamp("2021-05-01 15:00:00")
anISO8601Date: timestamp("2021-05-01T15:00:00Z")
aDate: date("2021-05-01")
}
Array literals
gelly
query {
someNumbers: [1, 2, 3]
someStrings: ["foo", "bar", "baz"]
myStuff: [1, "foo", true, null]
}
Object literals
gelly
query {
anObject: {foo: "bar", baz: true}
}

Built-in Operators

Boolean Logic

Logical not
gelly
query {
!false # returns true
}
The number line
gelly
1query {
2 true && true # returns true
3 true && false # returns false
4 true || false # returns true
5 false || false # returns false
6 }

Equality and Inequality

Expression Equality
gelly
1query {
2 1 == 1 # returns true
3 1 == 2 # returns false
4 true == true # returns true
5 true == false # returns false
6 }
Expression Inequality
gelly
1query {
2 1 != 1 # returns false
3 1 != 2 # returns true
4 true != true # returns false
5 true != false # returns true
6 }

Numeric Ordering

The number line
gelly
query {
1 > 1 # returns false
1 >= 1 # returns true
10 > 1 # returns true
}

Arethmetic

Back to elementary school
gelly
query {
1 + 1 # returns 2
2 * 10 # returns 10
10 / 2 # returns 5
}
Division
gelly
query {
10 / 3 # returns 3.3 repeating
}
Modulus
gelly
query {
10 % 3 # returns 1
}

String Functions

concat(<string:> [String!]!, delimiter: String): String!

Concatenate string literals together
gelly
query {
concat(["Hello", "", "world!"])
}
Concatenate fields from a selection together
gelly
query {
posts {
details: concat([title, " by ", author.name])
}
}
Concatenate array with a delimiter
gelly
query {
posts {
details: concat(tags, delimiter: ", ")
}
}

leftSlice(<string:> String!, length: Number): String!

leftSlice a string
gelly
query {
leftSlice("foobar", length: 3) # returns "foo"
}

length(<string:> String!): Integer!

get the length of a string
gelly
query {
length("foobar") # returns 6
}

lower(<string:> String!): String!

lowercase a string
gelly
query {
lower("FooBar") # returns "foobar"
}

rightSlice(<string:> String!, length: Number): String!

Rightslice a string
gelly
query {
rightSlice("foobar", length: 3) # returns "bar"
}

slice(<string:> String!, start: Number = 0, length: Number): String!

Slice a string from the start
gelly
query {
slice("foobar", length: 3) # returns "foo"
}
Slice a string in the middle
gelly
query {
slice("foobar", start: 2, length: 3) # returns "oba"
}
Slice a string in the middle
gelly
query {
slice("foobar", start: 4) # returns "ar"
}

upper(<string:> String!): String!

uppercase a string
gelly
query {
upper("FooBar") # returns "FOOBAR"
}

Aggregation Functions

The where argument

Count the number of published posts
gelly
query {
posts {
count(id, where: isPublished)
}
}
Count the number of published posts
gelly
1query {
2 posts {
3 count(id)
4 [where isPublished]
5 }
6 }
Aggregate posts with different filters
gelly
1query {
2 posts {
3 totalCount: count(id)
4 publishedCount: count(id, where: isPublished)
5 highScoreCount: count(id, where: score > 10)
6 bannedCount: count(id, where: author.banned)
7 }
8 }

avg(<number:> Number!, where: Boolean): Number!

Average all post scores by author
gelly
1query {
2 posts {
3 avg(score)
4 [group by author.name]
5 }
6 }
Average only published post scores
gelly
query {
posts {
avg(score, where: isPublished)
}
}

`every(where: Boolean): Boolean!

Check if all posts have been published
gelly
query {
posts {
every(published)
}
}
Check if all published posts have a high score
gelly
1query {
2 posts {
3 every(score > 10)
4 [where published]
5 }
6 }

count(<value:> Any, where: Boolean): Integer!

Count the number of posts
gelly
query {
posts {
count(id)
}
}
Count the number of published posts
gelly
query {
posts {
count(id, where: isPublished)
}
}
Get the average score and count of published posts
gelly
1query {
2 posts {
3 count(id)
4 avg(score)
5 [where published]
6 }
7 }

max(<number:> Number!, where: Boolean): Number!

Find the maxmium post scores by author
gelly
1query {
2 posts {
3 max(score)
4 [group by author.name]
5 }
6 }
Maximum pubished post score
gelly
query {
posts {
max(score, where: isPublished)
}
}

min(<number:> Number!, where: Boolean): Number!

Find the minimum post scores by author
gelly
1query {
2 posts {
3 min(score)
4 [group by author.name]
5 }
6 }
Minimum published post score
gelly
query {
posts {
min(score, where: isPublished)
}
}

sum(<number:> Number!, where: Boolean): Number!

Get the total votes cast by author
gelly
1query {
2 posts {
3 sum(voteCount)
4 [group by author.name]
5 }
6 }
Maximum pubished post score
gelly
query {
posts {
max(score, where: isPublished)
}
}

Time Functions

date(input: String!): DateTime!

Create a DateTime object
gelly
query {
date("2021-05-05")
}
Posts scheduled for publishing after a certain threshold
gelly
1query {
2 posts {
3 id
4 publishAt
5 [where publishAt > date("2021-05-05")]
6 }
7 }

datePart(part: String!, date: DateTime!): Number!

Get the year of a date
gelly
query {
datePart("year", date("2021-05-05"))
}
Day of week publishing schedule
gelly
1query {
2 posts {
3 id
4 publishDay: datePart("dow", publishAt)
5 }
6 }

interval(input: String!): Interval!

Create an Interval value
gelly
query {
short: interval("5 minutes")
long: interval("1 year")
longer: interval("1 year") + interval("6 months")
}
Posts published in the last 60 days
gelly
1query {
2 posts {
3 id
4 publishAt
5 [where publishAt > now() - interval("60 days")]
6 }
7 }

now(): DateTime!

Current Time
gelly
query {
now()
}
Posts scheduled for publishing in the future
gelly
1query {
2 posts {
3 id
4 publishAt
5 [where publishAt > now()]
6 }
7 }
Posts scheduled for publishing in the future
gelly
1query {
2 posts {
3 id
4 publishAt
5 [where publishAt > now()]
6 }
7 }

timestamp(input: String!): DateTime!

Create a DateTime value
gelly
query {
timestamp("2021-05-05 10:10:00")
}
Posts scheduled for publishing after a certain threshold
gelly
1query {
2 posts {
3 id
4 publishAt
5 [where publishAt > timestamp("2021-05-01T15:00:00Z")]
6 }
7 }

Numeric Functions

abs(<number:> Number!): Integer!

Absolute value
gelly
query {
abs(-10) # returns 10
abs(10) # returns 10
}

ceil(<number:> Number!): Integer!

Ceiling numbers
gelly
1query {
2 ceil(2.5) # returns 3
3 ceil(3) # returns 3
4 ceil(-2.5) # returns -2
5 ceil(-1) # returns -1
6 }

floor(<number:> Number!): Integer!

Flooring numbers
gelly
1query {
2 floor(2.5) # returns 2
3 floor(3) # returns 3
4 floor(-2.5) # returns -3
5 floor(-1) # returns -1
6 }

exp(<number:> Number!): Number!

Exponential of numbers
gelly
query {
exp(1) # returns 2.7182818284590452
}

ln(<number:> Number!): Number!

Natural Logarithm of numbers
gelly
query {
ln(1) # returns 0
ln(10) # returns 2.302585092994046
}

log(<number:> Number!, base: Number = 10): Number!

Natural Logarithm of numbers
gelly
query {
log(10) # returns 1
log(10, base: 2) # returns 0.1505149978319906
}

mod

power(<number:> Number!, exponent: Number!): Number!

Natural Logarithm of numbers
gelly
query {
power(10, 3) # returns 100
power(2, 5) # returns 32
}

round(<number:> Number!, precision: Number = 0): Number!

Rounding numbers
gelly
1query {
2 round(1) # returns 1
3 round(1.11111) # returns 1
4 round(1, precision: 2) # returns 1
5 round(1.11111, precision: 2) # returns 1.11
6 }

sign(<number:> Number!): Number!

sqrt(<number:> Number!): Number!

Number square roots
gelly
query {
sqrt(4) # returns 2
sqrt(10) # returns 3.162277660168379
}

trunc(<number:> Number!, precision: Number = 0): Number!

Number square roots
gelly
1query {
2 trunc(1) # returns 1
3 trunc(1.11111) # returns 1
4 trunc(1.111111, precision: 2 # returns 1.11
5 trunc(1, precision: 2) # returns 1
6 }

random(): Number!

Trigonometric Functions and Constants

acos(<number:> Number!): Number!

asin(<number:> Number!): Number!

atan(<number:> Number!): Number!

cos(<number:> Number!): Number!

cot(<number:> Number!): Number!

degrees(<radians:> Number!): Number!

pi

radians(<degrees:> Number!): Number!

sin(<number:> Number!): Number!

tan(<number:> Number!): Number!

GraphQL differences