# Queries

A GraphQL query is used for fetching data. This can be useful for verifying which data is stored for a given object class, or for a third party to export data from your solution.

{% hint style="info" %}
**Good to know**

Queries can be built by using the [GraphiQL Explorer](https://docs.appfarm.io/reference/data-model/graphql/..#graphiql-explorer). Simply select what to query, and the IDE will handle the syntax!
{% endhint %}

## Simple queries

The simplest query you can run is to specify the object class (known as an *object type* in GraphQL). For example, if you wanted to list all Projects in the database, you could write:

```graphql
{
	project
}
```

Note that the name of the object class is specified under **Endpoint Name** in the object class properties in Appfarm Create.

Click the Play button (or Cmd/Ctrl + Enter) to execute the query. The response will be displayed to the right.

The query editor will also edit your query to contain all the properties (*fields* in GraphQL) that are available to query:

```graphql
{
  project {
    _id
    title
    description
    createdDate
    createdBy
    status
    projectNumber
    projectDisplayName
    af_createdDate
    af_updatedDate
  }
}
```

You can use these fields in your query to customize the response that you receive. For example, the following query will only return the id and title properties of each project:

```graphql
{
  project {
    _id
    title
  }
}
```

To further refine your query you can include arguments, see advanced queries.

### Reference objects

If a queried object references another object, or is referenced by another object, you can extract details about the other object.

For example, if you have projects with tasks, you might like to list out the tasks for a project, or obtain the project details for a given task.

```graphql
// Return all projects, with their ID, title, and an array of associated tasks with each task's ID and title
{project {
  _id
  title
  taskList {
    _id
    title
  }
}}

// Return all tasks with their ID, title, and an object containing the title and description of the associated project
{task {
  _id
  title
  project_reference {
    title
    description
  }
}}
```

## Advanced queries

More advanced query operators can be used to further customize the response. In the following examples, *Book* is queried in different ways.

### Limit

Restrict the response to contain only `n` objects.

```graphql
// Return a maximum of 2 books, and only return the title
{
  Book(limit: 2){
    title
  }
}
```

### Skip

Skip the first `n` objects in the response.

```graphql
// Return every book after the first 2, and only return the title
{
  Book(skip: 2){
    title
  }
}
```

### Sort

Sort the response in ascending (ASC) or descending (DESC) order.

```graphql
// Return all books, sorted in ascending order by number of pages
{
  Book(sort: {pages: ASC}){
    title
    pages
  }
}
```

### Filter

Combine operators to filter the response.

```graphql
// Return all books with more than 500 pages
{
  Book(filter: {
    pages: {gt: 500}
  }){
    title
    pages
  }
}

// Return all books with more than 500 pages, sorted by title
{
  Book(
    filter: {pages: {gt: 500}},
    sort: {title: ASC}
    ){
    title
    pages
  }
}

// Return all books with more than 500 pages but less than or equal to 1000 pages
{
  Book(filter: {
    and: [{pages: {gt: 500}}, {pages: {lte: 1000}}]
  }){
    title
    pages
  }
}

// Return all books with more than 500 pages but less than or equal to 1000 pages and with the title "Jane Eyre"
{
  Book(filter: {
    or: [
      {and: [{pages: {gt: 500}}, {pages: {lte: 1000}}]},
      {title: {eq: "Jane Eyre"}}
    ]
  }){
    title
    pages
  }
}

// Return all books with the title "Jane Eyre" or "Wuthering Heights"
{
  Book(filter: {
    title: {in: ["Jane Eyre","Wuthering Heights"]}
  }){
    title
    pages
  }
}
```

The supported **filter operators** are `and`, `or`, `not`, `nor`, `eq`, `ne`, `in`, `nin`, `gt`, `gte`, `lt`, `lte`. Each filter operator will be explained by example:&#x20;

#### **and**

Example:

```graphql
{
  Book(filter: {
    and: [{pages: {gt: 500}}, {pages: {lte: 1000}}]
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `pages` field is greater than `500` **and** the `pages` field is less than or equal `1000`

#### **or**

Example:

```graphql
{
  Book(filter: {
      or: [
      {and: [{pages: {gt: 500}}, {pages: {lte: 1000}}]},
      {title: {eq: "Jane Eyre"}}
    ]
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `pages` field is greater than `500` **and** the `pages` field is less than or equal `1000`

&#x20; or

* the `title` field equals `Jane Eyre`

#### not

Example:

```graphql
{
  Book(filter: {
      pages: {not: {gt: 500}}
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `pages` field is **not** greater than `500` (in other words, 499 or less)

#### nor ("not or")

Example:

```graphql
{
  Book(filter: {
      nor: [{price: {eq: 1.99}}, {sale: {eq: true}}]
  }){
    title
    price
    sale
  }
}
```

This query will return all books that

* contain the `price` field whose value is *not* equal to `1.99` and contain the `sale` field whose value *is not* equal to `true` **or**
* contain the `price` field whose value is *not* equal to `1.99` *but* do *not* contain the `sale` field **or**
* do *not* contain the `price` field *but* contain the `sale` field whose value *is not* equal to `true` **or**
* do *not* contain the `price` field *and* do *not* contain the `sale` field

#### eq ("equals")

This operator is used for comparison. Example:

```graphql
{
  Book(filter: {
    title: {eq: "Jane Eyre"}
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `title` field equals `Jane Eyre`

#### ne ("not equals")

This operator is used for comparison. Example:

```graphql
{
  Book(filter: {
    title: {ne: "Jane Eyre"}
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `title` field **not equals** `Jane Eyre`

#### in ("in the set" / "is any of")

This operator is used for comparison. Example:

```graphql
{
  Book(filter: {
   title: {in: ["Jane Eyre","Wuthering Heights"]}
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `title` field is any of`Jane Eyre` or `Wuthering Heights` (or rephrased: the value of the `title` field is **in** the set of the values `Jane Eyre` and `Wuthering Heights`)

#### nin ("not in the set" / "none of")

This operator is used for comparison. Example:

```graphql
{
  Book(filter: {
   title: {nin: ["Jane Eyre","Wuthering Heights"]}
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `title` field is none of`Jane Eyre` or `Wuthering Heights` (or rephrased: the value of the `title` field is **not in** the set of the values `Jane Eyre` and `Wuthering Heights`)

#### gt ("greater than")

This operator is used for comparison. Example:

```graphql
{
  Book(filter: {
    pages: {gt: 500}
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `pages`field is **greater than** `500` (i.e. 501 pages or more)

#### gte ("greater than or equal")

This operator is used for comparison. Example:

```graphql
{
  Book(filter: {
    pages: {gte: 500}
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `pages`field is **greater than or equal** `500` (i.e. 500 pages or more)

#### lt ("less than")

This operator is used for comparison. Example:

```graphql
{
  Book(filter: {
    pages: {lt: 500}
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `pages`field is **less than** `500` (i.e. 499 pages or less)

#### lte ("less than or equal")

This operator is used for comparison. Example:

```graphql
{
  Book(filter: {
    pages: {lte: 500}
  }){
    title
    pages
  }
}
```

This query will return all books where

* the `pages`field is **less than or equal** `500` (i.e. 500 pages or less)

### Count

You can query the total number of objects in a response by using the **Count** query type. This needs to be enabled per object class by selecting **Enable Aggregate** and granting the **Aggregate** permission to the appropriate role.

When enabled, a new query type is added to your available queries. Using the object class *Order* as an example, we would get access to *countOrder*. This is separate to the *order* query type for reading data.

```graphql
// Return a count of all orders
{
  countOrder {
    count
  }
}
```

```graphql
// Return a count of all orders made on or after the 1st of September 2022
{
  countOrder(filter: {orderDate: {gte: "2022-09-01"}}){
    count
  }
}
```

### Aggregate and grouping

You can summarize or find average, min/max or standard deviation using GraphQL aggregates. You may also group the records. For example, you may find the total order amount from OrderLines per Product:

```graphql
{aggregateOrderLine( 
  filter: {product: {ne: null}},  
  sort: {productNumber:DESC}, 
  group: product,  
) { 
    product
    productNumber
    sum: amount_sum
    _count
  }
}
```

Given the above example with an OrderLine object class, you may perform the following:

* Filter, Sort or Group on any property (optional)
* In the list of properties to be returned, you may select the first or last entry. For example, we might return `customer_first` or `customer_last` for in the above expression for returning the first or last customer of the grouped list of order lines.
* In the list of properties to be returned, we may select the following aggregates of *numbers* (with `amount` as example):&#x20;
  * `amount_sum` (**sum** of the amount of orderLines)
  * `amount_avg` (**average** of the amount of orderLines)
  * `amount_max` (**maximum** of the amount of orderLines)
  * `amount_min` (**minimum** of the amount of orderLines)
  * `amount_stdDevPop` (**standard deviation** of the amount of *all* orderLines / the whole population)
  * `amount_stdDevSamp` (**standard deviation** of the amount of orderLines in the returned sample)
  * `amount_first` (amount of the first orderLine)
  * `amount_last` (amount of the last orderLine)
* You may select to return an alias for a property, as in the above example `sum: amount_sum` (`sum` is an alias for `amount_sum`)

As with [Count](#count), this needs to be enabled per object class by selecting **Enable Aggregate** and granting the **Aggregate** permission to the appropriate role.

{% hint style="info" %}
**Good to know**

If your Solution requires complex data analysis and heavy aggregation workflows, you might benefit from Data Aggregation Service. This add-on provides access to specialized database infrastructure that caters exclusively to analytics and aggregation workloads. Read more in our [Product Glossary](https://policies.appfarm.io/glossary/product-glossary#data-aggregation-service).
{% endhint %}

### Group by multiple properties

Following the example above, records can also be grouped by multiple properties. For instance, finding the total order amount from OrderLines per product and size. This will return one aggregation per unique pair of values for product and size:

```graphql
{aggregateOrderLine( 
  filter: {product: {ne: null}},  
  sort: {productNumber:DESC}, 
  groupList: [product, size]  
) { 
    product
    size
    productNumber
    sum: amount_sum
    _count
  }
}
```

### Run GraphQL Queries from Appfarm

GraphQL aggregations may be handy in applications with large amounts of data. With aggregation in GraphQL you may aggregate data on database level before it is returned to the client.

It is pretty straight forward.

1. Create an **API Key** in Appfarm Create. Go to **Service Accounts** in Appfarm Create, and locate (or create) a Service Account that is member of a Role with `Read` and `Aggregate` Permissions to the Object Classes to be queried in GraphQL
2. Use the Web Request to run the Query:
   * URL: `https://<HOSTNAME>/api/graphql`
   * Query Parameters: 1 parameter named `query`. Paste the query itself (e.g. `{aggregateOrderLine(filter: ...)}` as value
   * Result mapping: Map the properties returned from the GraphQL aggregation

Example setup, with mapping of the `Sum` to existing Product objects

<div align="left"><figure><img src="https://29237295-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MiLU-xcHu0eLZiTxcmZ%2Fuploads%2FuKazuTWoP3e4J361s2rA%2FWeb%20Request.png?alt=media&#x26;token=50d66025-72cf-455b-a6f3-c3517bbafa09" alt=""><figcaption><p>Web Request setup for aggregating using GraphQL</p></figcaption></figure></div>

{% hint style="info" %}
In the above example, we add the graphQL query as a Query Parameter of a GET request. If the graphQL query is too large, you might encounter `431 (Request Header Fields Too Large)` error. \
\
GraphQL also supports POST requests. You may add the query as the body of a POST request instead, e.g. the body of the above example would be `{"query":"{aggregateOrderLine(filter: ...)}"}`
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.appfarm.io/reference/data-model/graphql/queries.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
