Session: Querying: How to Work with Suggestions

The Suggestion feature is available through query extension methods. It gives you the ability to find word similarities using string distance algorithms.

Syntax

ISuggestionQuery<T> SuggestUsing<T>(SuggestionBase suggestion);

ISuggestionQuery<T> SuggestUsing<T>(Action<ISuggestionBuilder<T>> builder);
Parameters
suggestion SuggestionBase Defines the type of suggestion that should be executed
builder Action<ISuggestionBuilder<T>> Builder with a fluent API that constructs a SuggestionBase instance

Builder

ISuggestionOperations<T> ByField(string fieldName, string term);

ISuggestionOperations<T> ByField(string fieldName, string[] terms);

ISuggestionOperations<T> ByField(Expression<Func<T, object>> path, string term);

ISuggestionOperations<T> ByField(Expression<Func<T, object>> path, string[] terms);

ISuggestionOperations<T> WithOptions(SuggestionOptions options);

ISuggestionOperations<T> WithDisplayName(string displayName);
Parameters
fieldName string Points to the index field that should be used for operation
path Expression<Func<T, object>> Points to the index field that should be used for operation
term string Term that will be used as a basis of the suggestions
terms string[] Terms that will be used as a basis of the suggestions
displayName string User defined friendly name for suggestion result. If null, field name will be used.
options SuggestionOptions Non-default options that should be used for operation

Options

public int PageSize { get; set; } = 15;

public StringDistanceTypes? Distance { get; set; } = StringDistanceTypes.Levenshtein;

public float? Accuracy { get; set; } = 0.5f;

public SuggestionSortMode SortMode { get; set; } = SuggestionSortMode.Popularity;
Options
PageSize int Maximum number of suggestions that will be returned
Distance StringDistanceTypes String distance algorithm to use (None, Levenshtein, JaroWinkler, NGram)
Accuracy float? Suggestion accuracy
SortMode SuggestionSortMode Indicates in what order the results should be returned (None, Popularity)

Multiple suggestions

You are able to ask for multiple suggestions using a single query.

ISuggestionQuery<T> AndSuggestUsing(SuggestionBase suggestion);

ISuggestionQuery<T> AndSuggestUsing(Action<ISuggestionBuilder<T>> builder);

Example I

Dictionary<string, SuggestionResult> suggestions = session
    .Query<Employee, Employees_ByFullName>()
    .SuggestUsing(builder => builder
        .ByField("FullName", "johne")
        .WithOptions(new SuggestionOptions
        {
            Accuracy = 0.4f,
            PageSize = 5,
            Distance = StringDistanceTypes.JaroWinkler,
            SortMode = SuggestionSortMode.Popularity
        }))
    .Execute();
Dictionary<string, SuggestionResult> suggestions = await asyncSession
    .Query<Employee, Employees_ByFullName>()
    .SuggestUsing(builder => builder
        .ByField("FullName", "johne")
        .WithOptions(new SuggestionOptions
        {
            Accuracy = 0.4f,
            PageSize = 5,
            Distance = StringDistanceTypes.JaroWinkler,
            SortMode = SuggestionSortMode.Popularity
        }))
    .ExecuteAsync();
from index 'Employees/ByFullName' 
select suggest('FullName', 'johne', '{ "Accuracy" : 0.4, "PageSize" : 5, "Distance" : "JaroWinkler", "SortMode" : "Popularity" }')

Example II

Dictionary<string, SuggestionResult> suggestions = session
    .Query<Employee, Employees_ByFullName>()
    .SuggestUsing(new SuggestionWithTerm("FullName") { Term = "johne" })
    .Execute();
Dictionary<string, SuggestionResult> suggestions = await asyncSession
    .Query<Employee, Employees_ByFullName>()
    .SuggestUsing(new SuggestionWithTerm("FullName") { Term = "johne" })
    .ExecuteAsync();
from index 'Employees/ByFullName' 
select suggest('FullName', 'johne')

Example III

Looking for suggestions with dynamic query usage for multiple fields:

Dictionary<string, SuggestionResult> suggestions = session.Query<Employee>()
    .SuggestUsing(x => x
        .ByField(y => y.FirstName, "johne")
        .WithDisplayName("CustomLastName"))
    .AndSuggestUsing(x => x
        .ByField(y => y.LastName, "owen"))
    .Execute();
Dictionary<string, SuggestionResult> suggestions = await asyncSession.Query<Employee>()
    .SuggestUsing(x => x
        .ByField(y => y.FirstName, "johne")
        .WithDisplayName("CustomFirstName"))
    .AndSuggestUsing(x => x
        .ByField(y => y.LastName, "owen"))
    .ExecuteAsync();
from Employees 
select suggest('FirstName', 'johne') as CustomFirstName, suggest('LastName', 'owen')