Wednesday, December 17, 2014

S15E11: FAST Query Language (FQL) – The Unwanted Step Son

Want the book? Go get it!

This is the eleventh episode in my series “SharePoint Search Queries Explained - The Series”. See the intro post for links to all episodes.

In the first two episodes of the series I covered KQL and a couple of the new operators introduced with SharePoint 2013 which came from FQL - XRANK, NEAR and ONEAR.
In addition FQL has even more operators, some of them listed below:
  • starts-with
  • ends-width
  • count
  • andnot
  • range
There are also other operators which gives you great control over how a query is being sent over and parsed, and I recommend reading over the samples at FAST Query Language (FQL) syntax reference.

The post title plays at the fact that FQL is sort of hidden away, and no one really talks about it while the underlying search engine (and the refiner UI) in SharePoint (still) uses FQL.

This means KQL statements are translated to FQL before being executed. If this will hold true forever no one knows, but probably until that part of the search engine is being rewritten at some point – and this is good news as FQL has some tricks up it sleeve compared to the polished KQL counterpart.

Syntax

A notable difference between KQL and FQL is the query syntax. Where KQL typically writes

exp OPERATOR exp OPERATOR exp

FQL uses a nested syntax

OPERATOR(OPERATOR(exp,exp),OPERATOR(exp,exp))

Operators can also be combined in different ways, and you may achieve the same result with different ways of writing a query.
KQL: foo OR bar can in FQL be expressed as
  • or(foo,bar)`
  • string("foo bar", mode="or")
KQL: title="foo bar" title="zoo animal" can in FQL be expressed as
  • or(title:equals("foo bar"),title:equals("zoo animal"))
  • title:equals(or("foo bar","zoo animal"))
KQL: id=1 id=3 id=4 id=10 id=12 can in FQL be expressed as
  • id:int("1 3 4 10 12", mode="or")

Personally the FQL operators I find most useful are starts-with and ends-with which can be used to find matching terms at the start and end of a field. You cannot do wildcard matches with starts-with/ends-with, only term based matching.  KQL supports equals (=) and contains (:), but no matching at the start or end. You would typically use this against a managed property like a phone number. 555-1234
  • phonenumber:starts-with("555")
  • phonenumber:ends-with("1234")

Query on dates

Another useful scenario is when you want to filter on dates with a higher resolution than day. KQL will disregard any time portion of a date query while FQL will honor it. The sample below will return all documents produced after 12:35:57GMT.

write:range(2014-12-15T12:35:57.0000000Z,max,from="gt")

Querying using FQL

If you want to run a query using FQL you either have to use an FQL enables result source, where you on your REST or SSOM query set enableFQL to true. As far as I know you cannot do this using CSOM.

The easier and perhaps better alternative is to write your FQL statements as refinement filters. Refiner statements are by default sent over as FQL filters and enables a very powerful query feature by combining KQL and FQL in the same query. Note that FQL sent in the refinement part will not be part of the ranked expression – except with explicit XRANK statements.

Summary

If you ever find a scenario where KQL just don’t cut it, then take look at FQL and see if it provides the missing functionality you are looking for.

References: