GraphQL
Tutorial 4 - Advanced Filtering
23min
following on from the previous tutorial, we'll look at more advanced filtering options and show how you can filter with multiple rules prerequisites you have completed the learning graphql tutorials 1 3 about graphql optional read more about graphql and when it might be best used introduction in the last tutorial, we looked at how to filter your results so that only items from webapp 1 were returned we also challenged you to see if you could adjust the query so that it returned all webapp items this time, we'll look at filtering by different fields, or properties filtering with different kinds of rules using more than one filter at once filtering by properties some fields in records are defined in the graphql schema, like table , this often means they have their own filter option in the documentation siteglide fields, and your own custom fields, are very likely to be custom "properties" which are not directly defined by the schema if you're not sure, check the schema for the field you're looking for if you can't find it, it's a property for example, release date is not a custom field in the siteglide admin, but it's not in the list of available fields to filter by in the schema so we'll need to use properties a brief note on name you'll see the term name available in the schema but this is a deprecated way of referring to the table e g webapp 1 to fetch the name of the item in the siteglide admin, you'll need properties name in our next example query, we'll demonstrate this let's search for items with a properties name that contains the string "music" code query get items with musical names { records( page 1 per page 20 filter { properties { name "name", contains "music" } } ) { total pages results { table properties } } } notes see that properties uses a colon and then curly braces { } as we have usually used so far properties can instead be used to store an array of filter objects, but we'll look at this later note that we have to specify inside the curly braces both the name of the property we want to filter by (which happens here to also be called name , but it could also have been something else like release date ) and the method we'll be matching the value by, in this case contains music explorer adding a single filter to properties can be done with the explorer wizard however, if you want to be able to filter by an array of different properties, explorer has no support for this yet, but it is possible by writing in the query manually filtering data types other than strings in the examples so far, we've only filtered by strings or in other words, groups of letters or characters next we'll look at some other data types booleans integers / epoch date stamps arrays filtering by booleans a good example of a boolean property in siteglide is enabled this is a property which is stored as either true or false let's find all the items which are currently enabled code query get enabled items { records( page 1 per page 20 filter { properties { name "enabled", value boolean true } } ) { total pages results { table properties } } } notes again, we need to specify the name of the property we'll be filtering by, this time enabled we'll use value boolean as the most appropriate way to match an exact boolean value it's not the only method we could choose from the documentation, but it's more specialised to filtering booleans, so is potentially faster explorer filtering by integers and epoch timestamp dates when filtering by integers (which also includes siteglide's release date and expiry date fields, as these are stored as epoch timestamps) you've got a choice whether to filter by values or a range of values filtering for properties which match an exact integer code query get heavily weighted items { records( page 1 per page 20 filter { properties { name "weighting", value int 1 } } ) { total pages results { table properties } } } notes value int works the same as value boolean but is designed to handle the different type of data more efficiently be aware that running this query yourself on a starter site may produce no results this is the correct result, because starter site does not at the time of writing ship with any weightings set if you add a weighting of 1 in the admin, you'll see it appear in the results explorer filtering for integer properties which fall inside a range most often, you'll want to use more complex comparisons for integers we'll look at how to do this next at the same time, we'll take a look at how siteglide normally formats dates the dates are stored in epoch timestamp format, which is an integer storing the number of seconds which have elapsed since the epoch you can convert a date of your choice to this format here https //www epochconverter com/ in this example, i'll use the time at the current time of writing 1582108820 let's query for all items which have already been released in other words, the value stored in release date should be less than, or equal to, the current timestamp when you're thinking about dates, you can think of "less than" as meaning "before" and "greater than" as meaning "after" so here we're asking for "items with a release date before now" code query items already released { records( page 1 per page 20 filter { properties { name "release date", range {lte "1582108820"} } } ) { total pages results { table properties } } } notes the range filter requires you create a new object { } containing some logical comparison operators you can choose between the operators in the documentation panel see below documentation panel available operators can be seen under rangefilter they are short for greater than , greater than or equal , less than and less than or equal explorer filtering by arrays an array is a list of data one good example in siteglide is category array , which stores a list of unique ids that refer to categories we can now write a query to find items in a particular category code query mens clothing { records( page 1 per page 2000 filter { properties { name "category array", value in \["158198"] } } ) { total pages results { table properties } } } notes value in is special to fields which have an array data type it takes an array of strings \["string 1", "string 2"] as its value here we are just using one category id as an example you could experiment with combinations of category ids explorer only partial support is currently available in explorer for this it's not so good at handling arrays so you can select the property in explorer, but you'll need to add the value manually into your query so firstly, implement with the wizard secondly, change the value manually in the code from value in "158198" to value in \["158198"] filtering by multiple fields for all the filters you've learned in this article and the previous article, you can apply more than one at once query released mens clothing products { records( page 1 per page 2000 filter { table {value "module 14/product"} properties \[ { name "category array", value in \["158198"] }, { name "release date", range {lte "1582108820"} } ] } ) { total pages results { table properties } } } notes in this example, table and properties are both chosen as filter options properties takes an array (denoted by square brackets \[ ] ) of objects (denoted by curly braces { } each pair of curly braces { } inside properties should contain the name of the property and an independent filtering method e g range or value which will be used using a combination of filters in this way generally follows and logic items must pass all of the filtering tests you choose before they are returned explorer unfortunately, arrays are not currently supported in explorer, so you'll have to enter this section of the query manually for now filtering by whether a property exists or doesn't exist! you can also find items where a property does, or doesn't exist in this example, we're looking for webapps where a meta title was not added code query webapps missing meta descriptions { records( page 1 per page 2000 filter { table {starts with "webapp"} properties \[ { name "meta title", exists false } ] } ) { total pages results { table properties } } } notes exists accepts a boolean, so you can use false or true this shouldn't be wrapped in quotes, because booleans don't require them explorer new filtering with or logic what if you are looking to filter records so you can find records which fit either one rule or another but don't need to match both rules? here's an example from the pos team of how you can use the "or" option when filtering in this example we get records where either a webapp field 1 1 exists or a field parent exists query { records(per page 2000, filter { or \[ { properties \[ { name "webapp field 1 1", exists true } ] }, { properties \[ {name "parent", exists true} ] } ] }) { results { id table properties } } } notes inside filter we add an or property and an array with square brackets \[] this array takes one or more objects with curly braces {} each object is compared with or logic within the object, you can use the same properties you might normally use inside filter you can add multiple filter properties inside each object, but these will be compared with and logic so, to filter records by those which have both ( webapp field 1 1 and webapp field 1 2 ) or "parent", you would do the following query { records(per page 2000, filter { or \[ { properties \[ { name "webapp field 1 1", exists true }, { name "webapp field 1 2", exists true } ] }, { properties \[ {name "parent", exists true} ] } ] }) { results { id table properties } } } challenge! see if you can write one query which uses multiple filters try and return records which meet these criteria they are an item from a record with a table starting with module they are enabled they have already been released they have not yet expired they have a weighting between 1 and 3 they have a meta title they fall into the posters category hint this search is so specific, that by default on starter site it will return no results try creating an ecommerce product which meets these criteria before you start that way, you'll know when you've succeeded it's unusual to run this many filters at once most of the time in a real use case, you'd have less to write than this! however, putting together everything you've done so far will be good practice we'll look at the answer to this challenge in the next article next time we'll look at a possible solution to our latest challenge question after that, we'll look at how to run a query on a real siteglide site for the first time and look at what you can do with the results