HomeDev GuideAPI Reference
Dev GuideAPI ReferenceLegal TermsDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Projections

Describes how to work with projections of search results in Optimizely Search & Navigation. Projecting search results allows you to refine search results for display, and has performance benefits.

Projecting search results lets you iterate over more suitable results for displaying search results and other listings. Also, because you select a subset of the indexed data, send only the required fields over the wire.

While the API supports returning instances of the actual type that is indexed (as long as you can instantiate it directly or configure the Client conventions), you should return matching objects as instances of a different type and project them. As with LINQ, you do this with a Select method.

The following code shows a projection from a type named BlogPost to a type named SearchResult.

var result = client.Search<BlogPost>()
  .Select(x => new SearchResult {
    Title = x.Title,
      Author = x.Author.Name
  })
  .GetResult();

Special methods

Generally, if you invoke a method in a select expression, it is invoked on the target object after fetching it from the search engine. In other words, if you changed the above example from Title = x.Title to Title = x.Title.ToLower(), the Title property is retrieved from the search engine, then ToLower executes on the client.

However, some extension methods get special treatment when parsed in a select expression. One is the AsHighlighted method. When using this, you can project fragments from the source text into the result object. See Highlight.

AsCropped lets you retrieve only the beginning of a longer text field. AsCropped requires a single integer parameter, which controls the maximum length of the returned text. Unlike the SubString method, no exception is thrown if the actual text is shorter than the requested maximum length. Here is a sample usage.

var result = client.Search<BlogPost>()
  .Select(x => new SearchResult {
    Title = x.Title.AsCropped(50),
      Author = x.Author.Name
  })
  .GetResult();

AsCropped tries to crop text to the specified maximum length without separating words.

📘

Note

Because the method uses a script on the search engine side, the execution is slower than projections that do not use it.

Limitations

The Optimizely Search & Navigation .NET client API's Select method is less powerful than the in-memory LINQ version, but it is powerful compared to most other LINQ providers.

The Select method's primary limitation is that it does not support projecting from complex types, except for enumerables of non-complex types. In other words, in the example above, you could not project the full Author object. However, you could project individual fields from the Author object to a complex object.

Another limitation is that the Select method can not project user-defined functions or delegates. A user-defined function can request and load the entire object, including the binary attachment fields and nested objects. Avoid using user-defined functions or delegates. Instead, explicitly declare the projection in the select expression.

Examples

In general, the Select method works as expected if you are used to working with the LINQ equivalent, but remember the limitation of being unable to project from complex objects. Below are more examples of the method.

var result = client.Search<BlogPost>()
  .Select(x => new {
    x.Title,
      AuthorName = x.Author.Name
  })
  .GetResult();

var result = client.Search<BlogPost>()
  .Select(x => new {
    x.Title,
      AuthorInfo = x.Author.Name + " id: " + x.Author.Id
  })
  .GetResult();

var result = client.Search<BlogPost>()
  .Select(x => x.Author.Id)
  .GetResult();

And avoid doing something like this.

var result = client.Search<BlogPost>()
  .Select(x => new {
    x.Title,
      Parent = GetParent(x) // This is the problematic row.
  })
  .GetResult();

Select and the fluent API

In general, call the Select method after calling the searching and filtering methods. Those methods depend on the type you are searching for rather than the type you are projecting search results to.