Where filter
Describes filtering on a document using the Where
method.
Beta
The Optimizely Graph .NET Client is in beta. Contact your Customer Success Manager for information.
The Where
method is built for the Where Filter condition for the query result.
The parameters for the Where
method are:
- A field name.
- An instance of the
IFilterOperator
interface that is combined and transformed to an Optimizely Graph filter query.
var filterOperator = // create a concrete instance of IFilterOperator
new StringFilterOperators()
.Contains("value");
var query = queryBuilder
.ForType<MyDocument>()
.Fields(x=>x.Property1, x=>x.Property2)
.Where(x=>x.Property1, filterOperator)
.ToQuery()
.BuildQueries();
There are four implementations of IFilterOperator
:
NumericFilterOperators
– The filter operators for the Number field type. Optimizely Graph supports integer and float type.BooleanFilterOperators
– The filter operators for the Boolean field type.DateFilterOperators
– Filter operators for the DateTime field type.StringFilterOperators
– Filter operators for the String field type.
Filter expression
The Optimizely Graph .NET Client supports built-in functions and boolean logical operators for the filter query. It is similar to the FIND client.
An example for filtering on an ArticlePage to show items where Name contains "Optimizely" AND Status is "Published":
var query = queryBuilder
.ForType<ArticlePage>()
.Fields(x=>x.Name, x=>x.MetaDescription)
.Where(x=>x.Name.Match(“Optimizely”) & x.Status.Eq("Published"))
.ToQuery()
.BuildQueries();
Boolean filter
AndFilter<T>
class – Wrap one or more conditions with an AND operator. Use And method to combine many filters.OrFilter<T>
class – Wrap one or more conditions with an OR operator. Use Or method to combine many filters.NotFilter<T>
class – Wrap one or more conditions with an NOT operator. Use Not method to combine many filters.
You can create one of the preceding classes using the BooleanFilter
class. Use static methods AndFilter()
, OrFilter()
, and NotFilter()
to create AndFilter
, OrFilter
, and NotFilter instances
respectively.
var andFilter = BooleanFilter
.AndFilter<HomePage>()
.And(x=>x.Name.Eq("Your page name"))
.And(x=>x.Status.Eq("Published"));
var query = queryBuilder
.ForType<ArticlePage>()
.Fields(x=>x.Name, x=>x.MetaDescription)
.Where(andFilter)
.ToQuery()
.BuildQueries();
You can use basic logical operators AND (&), OR (|), and NOT (!) for creating a boolean filter.
var andFilter = BooleanFilter
.AndFilter<HomePage>()
.And(x=>x.Name.Eq("Your page name"))
.And(x=>x.Status.Eq("Published"));
var query = queryBuilder
.ForType<ArticlePage>()
.Fields(x=>x.Name, x=>x.MetaDescription)
.Where(andFilter | x=>x.IsDraft.Eq(true)) // wrap OrFilter for combining 2 filters
.ToQuery()
.BuildQueries();
For the complex filter query, use a variable of filter operator.
IFilterOperator filterForField1 = //create filter operator for type of Field1
IFilterOperator filterForField2 = //create filter operator for type of Field2
IFilterOperator filterForField3 = //create filter operator for type of Field3
var query = queryBuilder
.ForType<MyDocument>()
.Fields(x=>x.Property1, x=>x.Property2)
.Where(x=> x.Field1, filterForField1)
.Where(x=>x.Field2, filterForField2)
.Where(x=>x.Field3, filterForField3)
.ToQuery()
.BuildQueries();
AND logic
When you use multiple filters on different fields, the AND logical is implicitly applied.
For example if you need filter on MyDocument where Field1.In(1,2,3) AND Field2.NotIn(4,5,6):
var query = queryBuilder
.ForType<MyDocument>()
.Where(x=> x.Field1.In(1,2,3))
.Where(x=> x.Field2.NotIn(4,5,6))
.ToQuery()
.BuildQueries();
Multiple Where
methods
Where
methodsDo not use multiple Where
methods for filtering on the same field. For example:
var query = queryBuilder
.ForType<MyDocument>()
.Fields(x=>x.Property1, x=>x.Property2)
.Where(x=> x.Property1.InRange(1,9))
.Where(x=> x.Property1.NotIn(4,5,6)) //invalid query
.ToQuery()
.BuildQueries();
Instead, there are other ways to build the same functionality:
Option 1 – Create an instance of IFilterOperator
for multiple filters on one field:
var filter = new NumericFilterOperators()
.InRange(1,9)
.NotIn(4,5,6);
var query = queryBuilder
.ForType<MyDocument>()
.Fields(x=>x.Property1, x=>x.Property2)
.Where(x=>x.Property1, filter) //Passing an IFilterOperator for Property1
.ToQuery()
.BuildQueries();
Option 2 – Use boolean logic operators to wrap the conditions:
var andFilter = BooleanFilter
.AndFilter<MyDocument>()
.And(x=>x.Property1.InRange(1,9)/*condition1*/, x=> x.Property2.NotIn(4,5,6)/*condition2*/);
var query = queryBuilder
.ForType<MyDocument>()
.Fields(x=>x.Property1, x=>x.Property2)
.Where(andFilter)
.ToQuery()
.BuildQueries();
//Or maybe
var query = queryBuilder
.ForType<MyDocument>()
.Fields(x=>x.Property1, x=>x.Property2)
.Where(x=>x.Property1.InRange(1,9) & x=>x.Property1.NotIn(4,5,6))) //use AND logic condtional
.ToQuery()
.BuildQueries();
Filters on IEnumerable property
Please visit How to deal with IEnumerable property blog for short and easy code. It will generates GraphQL query more faster (Please take a look in comments).
We provide other way to deal with IEnumerabe properties as below:
- If
T
is the simple type (string, int, long, float, double, boolean, datetime), just use as normal property:
public class MyDocument{
public IEnumerable<string> Ancestors{get;set;}
}
var query = queryBuilder
.ForType<MyDocument>()
.Fields(x=>x.Name, x=>x.Url)
.Where(x=> x.Ancestors.Eq("99d57529-61f2-47c0-80c0-f91eca6af1ac"))
.ToQuery()
.BuildQueries();
-
If
T
is a complex type, there are two options.-
Select
IEnumerable
property then the properties ofT
:public class Language{ public string Name{get;set;} public string DisplayName{get;set;} } public class MyDocument{ public IEnumerable<Language> ExistingLanguages{get;set;} } var query = queryBuilder .ForType<MyDocument>() .Fields(x=>x.Name, x=>x.Url) .Where(x=> x.ExistingLanguages, f=> f.Name.Eq("en")) .ToQuery() .BuildQueries();
-
The most efficient way for dealing with
IEnumberable<T>
whereT
is a complex type is create an extension method for pretending property typeIEnumberable<T>
to beT
. With that you can use all properties of typeT
when select, filter, or facet using a simple block of code. Ensure that the method name equals with property name.public static class CmsModelsExtension { ... public static ContentLanguageModel ExistingLanguages(this Content myprop) { return null; } } //now you want to select properties in ExistingLanguages field, just use method ExistingLanguages() instead of property ExistingLanguages : query.Fields(x=> x.ExistingLanguages().Name, x.ExistingLanguages().DisplayName) //filters query.Where(x=> x.ExistingLanguages().Name.StartWith("e")) //facets query.Facet(x=> x.ExistingLanguages().Name.FacetLimit(10))
-
See Tool tips: Optimizely Graph Client Tool and how to leverage CMS data models to build query blog for more information.
Note
- If you have filter on properties of an
IEnumerable<T>
field, use the following example:var query = queryBuilder .ForType<MyDocument>() .Fields(x=>x.Name, x=>x.Url) .Where(x=> x.ExistingLanguages, f=> f.Name.Eq("en")) .ToQuery() .BuildQueries();
- If you build many conditions on one field please create an instance of
IFilterOperator
. For example for filter language contains "en" but not "English" inDisplayName
var filterOperator = new StringFilterOperators().Contains("en").NotIn("English"); var query = queryBuilder .ForType<MyDocument>() .Fields(x=>x.DisplayName, x=>x.Url) .Where(x=> x.ExistingLanguages, f=> f.DisplayName, filterOperator) .ToQuery() .BuildQueries();
- Now combine both of them for more complex query. Lets assume you want to filter more than one conditions on both
Name
andDisplayName
, you should create a logical filter instance then combine them before use.Where
.var operatorForName = new StringFilterOperators().Like("en").Boost(2); var operatorForDisplayName = new StringFilterOperators().Eq("English").Boost(1); var andFilter = BooleanFilter .AndFilter<MyDocument>() .And(x=>x.ExistingLanguages, f => f.Name, operatorForName) .And(x=>x.ExistingLanguages, f => f.DisplayName, operatorForDisplayName); var query = queryBuilder .ForType<MyDocument>() .Fields(x=>x.Name, x=>x.Url) .Where(andFilter) .ToQuery() .BuildQueries();
Updated about 2 months ago