In my previous post, I sang praises for some of the built in features of the Sitecore JSS GraphQL endpoint. I think it's great what already exists, but what if we wanted to add something custom to our GraphQL endpoint? Well, we can. Imagine if we couldn't? Shortest post ever.

I recently published a custom Content Search API GraphQL query that was inspired by the built in query that ships with Sitecore JSS GraphQL. All of that code is available on GitHub here.

All of the existing structure is the same as the existing Content Search API query but I removed the fieldsEqual field and replaced it with conditions. I debated on keeping the same parameter name but decided against it because one part of it is a bit of a departure.

What I really wanted to implement was something that exposed some of the PredicateBuilder functionality in GraphQL. I really wanted to OR some field conditions together to build out the facets on my prototype search page.

My requirements were as follows:

  • Enable the ability to specify if a condition should be ORed
  • Allow for nested groupings of conditions

Enabling OR operations

Let's start with our existing GraphQL query:

{
  search(fieldsEqual:[
    {
      name:"category",
      value:"History"
    }
    {
      name:"category",
      value:"Math"
    }
  ]) {
    results {
      totalCount
    }
  }
}

Currently, this query just doesn't work for what we're trying to do. I really want to get all items that have the History or Math category configured on them. The category is a DropLink field though, so it's not possible for an item to have both.

If you've installed the custom search API query from the GitHub repository above, you should see customQuery on the Query object in GraphiQL on the endpoint you've enabled it on.

With this installed, we can rewrite our query to give us all items that match either of the provided tags.

{
  customSearch(conditions:[
    {
      name:"category",
      value:"History"
    }
    {
      name:"category",
      value:"Math",
      useor:true
    }
  ]) {
    results {
      totalCount
    }
  }
}

So we didn't have to change too much to enable that functionality. I changed the search field to customSearch and added the useor field to the second condition.

Enabling Grouping

I will admit, I almost didn't implement this. I liked how just enabling OR felt. I followed through with it though because I actually used this recently. I had the condition of executing the query and then adding a global condition to include a featured result. So the logic was (ALL OF THE QUERY LOGIC) OR (ITEM ID EQUALS SOME FEATURED PATH).

So an example grouped query looks as follows:

{
  customSearch(conditions:[
    {
      group:[
        {
          name:"category",
          value:"History"
        }
        {
          name:"category",
          value:"Math",
          useor:true
        }
      ]
    }
  ]) {
    results {
      totalCount
    }
  }
}

It's the same query as above, just nested in the group field. We can add another condition to mimic my featured item example that I described above as well.

{
  customSearch(conditions:[
    {
      group:[
        {
          name:"category",
          value:"History"
        }
        {
          name:"category",
          value:"Math",
          useor:true
        }
      ]
    },
    {
      name:"_fullpath",
      value:"/sitecore/content/home",
      useor: true
    }
  ]) {
    results {
      totalCount
    }
  }
}

Who wouldn't want to feature the homepage on every search query? You can also nest groups if you're into doing something like that.

{
  customSearch(conditions:[
    {
      group:[
        {
          name:"category",
          value:"History"
        }
        {
          group:[
            {
              name:"contenttype",
              value:"Article"
            }
          ],
          useor:true
        }
        {
          name:"category",
          value:"Math",
          useor:true
        }
      ]
    },
    {
      name:"_fullpath",
      value:"/sitecore/content/home",
      useor: true
    }
  ]) {
    results {
      totalCount
    }
  }
}

Conclusion

Overall, I'm happy with this new functionality. Check out the PredicateBuilder condition code. I'll be updating the search page I've discussed before to target this new query field in a future post. I feel like this functionality can really help build out some more complex situations when it comes to building out faceting and some global search conditions.