This content is archived. See latest version here.

Last updated: Nov 16 2015

Nested queries 

Nested queries in Episerver Find let you query a parent object and filter it on a child collection marked as "nested." This is particularly useful in solutions with Episerver Commerce and Find, to manage search queries in large catalog structures.

Nested field and types

Note: Episerver allows queries on complex types. If you want to query a value type or a string collection, use the Match or Exist filter.

Using function calls as nested fields

You can use functional calls, such as team.ForeignPlayers(), as a nested collection. The function must return an IEnumerable<TListItem> where TListItem:class.

Example: Include the function to be indexed (functions are not indexed by default).

client.Conventions.ForInstancesOf<Team>().IncludeField(team => team.ForeignPlayer());

Adding fields as nested types

To add desired fields as "nested" types, use one of these conventions, depending on your requirements.

Example: Nested property or function exists on a class, for example Team.

client.Conventions.NestedConventions.ForType<Team>().Add(team => team.Players);

Example: Nested property exists on an interface, for example, IPlayers (all implementations of this interface are marked as nested).

 client.Conventions.NestedConventions.ForType<IPlayers>().Add(team => team.Players);

Example: Custom convention, which allows for a custom implemention. Type and name can be used to determine whether a specific property should be marked as nested.

client.Conventions.NestedConventions.Add((type, name) => (typeof(IPlayers).IsAssignableFrom(type) && name.Equals("Players")));

The above syntax allows Find's indexing, searching, and filtering to treat that field as one whose children can be used in filtering. For example:

public class Team 
{
 public Team(string name)
 { 
  TeamName = name; 
  Players = new List<Player>();
 }
 public string TeamName { get; set; }
 public List<Player> Players { get; set; }
}

public class Player
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public int Salary { get; set; }
}

Index the content and start filtering:

result = client.Search<Team>()
 .Filter(x => x.Players, p => p.FirstName.Match("Cristiano") & 
    p.LastName.Match("Ronaldo"))
 .GetResult();

or

result = client.Search<Team>()
 .Filter(x => x.Players.MatchItem(p => p.FirstName.Match("Cristiano") &
    p.LastName.Match("Ronaldo")))
 .GetResult();

Sorting

To sort by nested properties, use the OrderBy extension, which takes a filter argument that specifies the nested object used to calculate the sort value.

result = client.Search<Team>()
 .Filter(x => x.Players, p => p.FirstName.Match("Cristiano"))
 .OrderBy(x => x.Players, p => p.LastName, p => p.FirstName.Match("Cristiano"))
 .GetResult();

or

result = client.Search<Team>()
 .Filter(x => x.Players, p => p.FirstName.Match("Cristiano"))
 .OrderByDescending(x => x.Players, p => p.LastName, p =>
    p.FirstName.Match("Cristiano"))
 .GetResult();

For int/DateTime, specify a SortMode (Min/Max/Avg/Sum) to determine how to treat multiple sort values. For example, to sort by maximum player salary on a team, use:

result = client.Search<Team>()
 .OrderByDescending(x => x.Players, p => p.Salary, SortMode.Max)
 .GetResult();

Facets

To create facets on nested properties, the TermsFacetFor/HistogramFacetFor/DateHistogramFacetFor extensions take an IEnumerable expression along with an item expression and optional filter.

result = client.Search<Team>()
 .TermsFacetFor(x => x.Players, x => x.FirstName)
 .GetResult();

or (to filter):

result = client.Search<Team>()
 .TermsFacetFor(x => x.Players, x => x.FirstName, x => x.LastName.Match("Ronaldo"))
 .GetResult();

and to fetch the result:

facet = result.TermsFacetFor(x => x.Players, x => x.FirstName);

Comments

Third sample of  registering NestedConventions does not seem to be available in EPiServer.Find version 11.0.0.3701. Only generic version of Add is available. Also, Expression is constrained to be MemberExpression, meaning that only properties or fields can be added to NestedConventions.

Hi Kaspars,

Thanks for your feedback. We are about to release a new version of EPiServer Find which includes the ablity to add functions as nested fields. Will ping you when the release is available