This content is archived. See latest version here

Last updated: Jun 10 2014

Introduction

While the API supports returning instances of the actual type that has been indexed (as long as it can be instantiated directly or by configuring the Client conventions), it often makes sense to return matching objects as instance of a different type, projecting them. Just like with LINQ this is done with a method named Select. Projecting search results have several benefits. It allows us to iterate over results more suitable for displaying search results and other types of listings. Further, by selecting a subset of the indexed data only a subset of the data, the fields actually required, has to be sent over the wire.

Example

A simple projection from a type named BlogPost to a type named SearchResult can look like this:

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

Special methods

In general, if you invoke a method in a select expression that method will be invoked on the target object after having fetched it from the search engine. In other words, if we were to change the above example from Titel = x.Title to Title = x.Title.ToLower() the Title property would be retrieved from the search engine and ToLower would be executed on the client. However, there are a couple of extension methods that are treated in special ways when parsed in a select expression. One is the AsHighlighted method using which we can project fragments from the source text into the result object. For more information about AsHighlighted, see the topic for highlighting.

Another such method is the AsCropped method using which we can retrieve only the beginning of a longer text field. The method requires a single integer parameter which controls the maximum length of the returned text. As opposed to the SubString method no exception will be thrown if the actual text is shorter than the requested maximum length. An example usage can look like this:

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

When using the AsCropped method it will attempt to crop the text to the maximum length specified without cutting individual words in half. Note that the method is implemented using a script on the search engine side meaning that the execution will be slower than projections not using it.

Limitations

The Select method in the EPiServer Find.NET client API naturally is not as powerfull as the in-memory LINQ version, but compared to most other LINQ providers it supports a lot.

The primary limitation of the Select method is that it does not support projecting from complex types except for enumerable of non-complex types. In other words, in the example above, we could not have projected the full Author object. However, we could have projected individual fields from the Author object to some complex object.

Further examples

In general the Select method works as expected if you are used to working with the LINQ equivalent and keep the limitation of not being able to project from complex objects in mind. Below are some further examples of what you can expect to work.

Projecting to anonymous type

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

Projecting multiple fields to a single field

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

Projecting from a complex type to a simple type

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

Select and the fluent API

Note that in general you will want to, and have to, call the Select method after you you call methods for searching and filtering and those depend on what type you are searching for rather than what type you project the search results to.


Do you have feedback on this documentation? Send an email to documentation@episerver.com. For development-related questions and discussions, refer to our Forums on https://world.episerver.com/forum/