28 Faceted search
Facets count the matching nodes per value or range of a property: what a filter sidebar shows. Call
.Facets() to switch the builder to facet mode, then name the facets:
var result = db.Query<IEvent>()
.Where(e => e.Status == EventStatus.Published)
.WhereSearch("jazz")
.Facets()
.AddValueFacet(e => e.Status) // a bucket per value
.AddRangeFacet(e => e.Price) // ranges chosen by the engine
.AddRangeFacet(e => e.Price, 0m, 250m) // …plus a range of your own
.AddFacet(e => e.Tags) // the engine picks values or ranges
.SetFacetOptions(e => e.Tags, maxValues: 20, minCount: 1, sortByCount: true)
.Page(0, 20)
.Execute();
foreach (var facet in result.Facets) {
Console.WriteLine(facet.DisplayName);
foreach (var v in facet.Values)
Console.WriteLine($" {v} ({v.Count}){(v.Selected ? " ←" : "")}");
}The result is a ResultSetFacets<T>: the page of nodes plus Facets and SourceCount, from one
query.
- Applying the user's selection — The same builder applies what the user clicks. A selected value filters the result and comes back with Selected set:
- Facet declaration methods — Each method takes the property as an expression, a name or an id. Faceting needs Indexed = true. NotFacet = true keeps a property out, and a relation takes part only with [RelationProperty(Facet = true)].
- Where the un-named facets come from — With no facet named, a facet query counts every facetable property of every node type in the result. Naming a facet turns this off. These methods choose explicitly, and combine with the facets you name:
- 28.1 Pivot tables — A pivot summarises the matching nodes as a table, like a spreadsheet pivot table. Rows and columns are groups of nodes by property value, and each cell holds measures over its nodes. A pivot returns the table, not the…
- 28.2 GroupBy — GroupBy is SQL's GROUP BY, written the way LINQ and EF Core write it. It is the typed, one-axis form of a pivot and runs on the same engine. Use it in application code, and a pivot for two axes, sub-totals, or tables…