How to order by multiple nested fields using GraphQL

I have the following GraphQL query:

{
  queryStepContents(orderby: "id") {
    data {
      question {
        iv {
          flatData {
            question
          }
        }
      }
      answer {
        iv {
          data {
            optionGroup {
              iv {
                data {
                  option {
                    iv {
                      flatData {
                        option
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

This results in the following response:

{
  "data": {
    "queryStepContents": [
      {
        "data": {
          "question": {
            "iv": [
              {
                "flatData": {
                  "question": "How old are you?"
                }
              }
            ]
          },
          "answer": {
            "iv": [
              {
                "data": {
                  "optionGroup": {
                    "iv": [
                      {
                        "data": {
                          "option": {
                            "iv": [
                              {
                                "flatData": {
                                  "option": "8"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "9"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "10"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "11"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "12"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "13"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "14"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "15"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "16"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "17"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "18"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "19"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "20"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "21"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "22"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "23"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "24"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "25"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "26"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "27"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "28"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "29"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "30"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "31"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "32"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "33"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "34"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "35"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "36"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "37"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "38"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "39"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "40"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "41"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "42"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "43"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "44"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "45"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "46"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "47"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "48"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "49"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "50"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "51"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "52"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "53"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "54"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "55"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "56"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "57"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "58"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "59"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "60"
                                }
                              }
                            ]
                          }
                        }
                      }
                    ]
                  }
                }
              }
            ]
          }
        }
      },
      {
        "data": {
          "question": {
            "iv": [
              {
                "flatData": {
                  "question": "Have you given birth?"
                }
              }
            ]
          },
          "answer": {
            "iv": [
              {
                "data": {
                  "optionGroup": {
                    "iv": [
                      {
                        "data": {
                          "option": {
                            "iv": [
                              {
                                "flatData": {
                                  "option": "Yes"
                                }
                              },
                              {
                                "flatData": {
                                  "option": "No"
                                }
                              }
                            ]
                          }
                        }
                      }
                    ]
                  }
                }
              }
            ]
          }
        }
      }
    ]
  }
}

The Step content items are indeed ordered by id. I’ve verified that and it’s working fine.

However, I would also like to order by option - i.e. I would like to first order by id for my step content items AND then order by id for my option content items. What is the syntax for doing that?

I’ve tried…

  option(orderby: "id") {
    iv {
      flatData {
        option
      }
    }
  }

…but that gives me validation errors.

It is basically the odata syntax: https://docs.squidex.io/02-documentation/developer-guides/api-overview/api#sorting

Thank you for the quick reply Sebastian but not sure I follow. Btw, I’m still new to GraphQL.

Since I’m using GraphQL I can’t append for instance ?$orderby=data/queryQuestionContents/lastModified asc to my GraphQL endpoint https://domain/api/content/my-app/graphql? The link you posted does not apply to GraphQL?

Ex: https://domain/api/content/my-app/graphql?$orderby=data/queryQuestionContents/lastModified asc <- This is not possible, correct?

My understanding is that appending sorting and filtering etc as a query string only applies to the regular content API:

https://domain/api/content/my-app/result

For GraphQL:

https://domain/api/content/my-app/graphql

you must orderby by doing for example: queryStepContents(orderby: "id").

queryStepContents(orderby: "id") works for me but I need to orderby using two fields. And one field is nested deep in my structure.

        {
          queryStepContents(orderby: "id") { <<<--- FIRST: ORDER BY ID FIELD OF STEP CONTENTS
            data {
              question {
                iv {
                  flatData {
                    question
                  }
                }
              }
              answer {
                iv {
                  data {
                    optionGroup {
                      iv {
                        data {
                          option { 
                            iv {
                              id
                              flatData {
                                id <<<--- SECOND: ORDER BY ID FIELD OF OPTION CONTENTS
                                option
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }

Maybe what I’m trying to do here is not possible?

Sorry, it seems I have misinterpreted your post.

You can only sort and filter what is directly part of your content. So not referenced and assets. Perhaps you can change in graphql query. If you have only few data, I would just sort it client side.

{
  queryStepContents(orderby: "data/id/iv") {
    data {
      id {
        iv
      }
    }
  }
}

Gives me an error:

{
  "data": {
    "queryStepContents": null
  },
  "errors": [
    {
      "message": "Failed to parse query: Could not find a property named 'id' on type 'MyAppDev.Step.Data'.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ]
}

Here is the result without orderby:

Query:

{
  queryStepContents {
    data {
      id {
        iv
      }
    }
  }
}

Response:

{
  "data": {
    "queryStepContents": [
      {
        "data": {
          "id": {
            "iv": 3
          }
        }
      },
      {
        "data": {
          "id": {
            "iv": 2
          }
        }
      },
      {
        "data": {
          "id": {
            "iv": 1
          }
        }
      }
    ]
  }
}

What am I doing wrong?

I am actually not sure, perhaps a caching issue?

Yes, looks like it because I created a new app and tested the exact same thing and it works.

Is there a way to refresh the cache?

The graphql schema is cached for a little bit, but not more than 10 min. A restart should definitely help. If it does not we have to dig into the issue.

I’m using Squidex version 5.5.0 btw. Reading through the changelog atm to see if I should upgrade or not.

I created the schema the other day. Made changes to it yesterday. Tried today but it seems it is still cached.

I will try to restart my app. I’ll let you know how it goes.

1 Like

Okay so I killed my Squidex pod, it came back, tried the same as above but I still get the error message:

{
  "data": {
    "queryStepContents": null
  },
  "errors": [
    {
      "message": "Failed to parse query: Could not find a property named 'id' on type 'MyApp.Step.Data'.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ]
}

Is there something else I could try, @Sebastian?

My Schema looks likes this:

{
    "properties": {},
    "scripts": {},
    "fieldsInLists": [],
    "fieldsInReferences": [],
    "fields": [
        {
            "name": "Id",
            "properties": {
                "isRequired": true,
                "fieldType": "Number",
                "editor": "Input",
                "inlineEditable": true,
                "isUnique": true,
                "label": "Id",
                "hints": "A unique identifier for a step schema item.",
                "placeholder": "Ex: 1, 2, 3, etc."
            },
            "partitioning": "invariant"
        },
        {
            "name": "question",
            "properties": {
                "isRequired": true,
                "fieldType": "References",
                "editor": "List",
                "minItems": 1,
                "maxItems": 1,
                "resolveReference": true,
                "mustBePublished": true,
                "schemaIds": [
                    "612c7ca7-74d1-48d0-98ce-be009b0f2abc"
                ],
                "label": "Question",
                "hints": "A reference to a question schema item."
            },
            "partitioning": "invariant"
        },
        {
            "name": "answer",
            "properties": {
                "isRequired": true,
                "fieldType": "References",
                "editor": "List",
                "mustBePublished": true,
                "schemaIds": [
                    "f0bdf71a-f006-4bc6-af6c-0358923cdfa9"
                ],
                "label": "Answer",
                "hints": "A reference to an answer schema item."
            },
            "partitioning": "invariant"
        }
    ],
    "isPublished": true
}

I think I found the problem.

My id field has the incorrect casing. Id instead of id.

I was very careful when naming my fields so not sure how id ended up as Id :thinking:

I think you can close this one now, @Sebastian. Thanks so much for the quick help!

1 Like

Shit happens … but have you tried it in graphiql? You should get autocompletion there.

Yes, I have. It suggests id (lowercase):

You can clearly see my misstake here :smiley:

Thats weird, Could be an old bug.