Query for Suggestions


  • Given a string term, the Suggestion feature will offer similar terms from your data.

  • Word similarities are found using string distance algorithms.

  • Examples in this article demonstrate getting suggestions with a dynamic-query.
    For getting suggestions with an index-query see query for suggestions with index.



What are terms

  • All queries in RavenDB use an index - learn more about that here.
    Whether making a dynamic query which generates an auto-index or using a static index,
    the data from your documents is 'broken' into terms that are kept in the index.

  • This tokenization process (what terms will be generated) depends on the analyzer used,
    various analyzers differ in the way they split the text stream. Learn more in Analyzers.

  • The terms can then be queried to retrieve matching documents that contain them.

When to use suggestions

Querying for suggestions is useful in the following scenarios:

  • When query has no results:

    • When searching for documents that match some condition on a given string term,
      if the term is misspelled then you will Not get any results.
      You can then ask RavenDB to suggest similar terms that do exist in the index.

    • The suggested terms can then be used in a new query to retrieve matching documents,
      or simply presented to the user asking what they meant to query.

  • When looking for alternative terms:

    • When simply searching for additional alternative terms for a term that does exist.

The resulting suggested terms will Not include the term for which you search,
they will only contain the similar terms.

Suggest terms - for a single term

Consider this example:
Based on the Northwind sample data, the following query has no resulting documents,
as no document in the Products collection contains the term chaig in its Name field.

/**
 * Usage:
 *   - suggestUsing(SuggestionBase $suggestion);
 *   - suggestUsing(Closure $suggestionBuilder);
 *
 * @param SuggestionBase|Closure|null $suggestionOrBuilder
 * @return SuggestionDocumentQueryInterface
 */
public function suggestUsing(null|SuggestionBase|Closure $suggestionOrBuilder): SuggestionDocumentQueryInterface;
  • Executing the above query will generate the auto-index Auto/Products/ByName.
    This auto-index will contain a list of all available terms from the document field Name.
    The generated terms are visible in the Studio - see image below.

  • If you suspect that the term chaig in the query criteria is written incorrectly,
    you can ask RavenDB to suggest existing terms that are similar to chaig, as follows:.

/**
 * Usage:
 *   - byField("fieldName", "term");
 *   - byField("fieldName", ["term1", "term2"]);
 */
function byField(?string $fieldName, null|string|StringArray|array $terms): SuggestionOperationsInterface;

function withOptions(?SuggestionOptions $options): SuggestionOperationsInterface;
$options = new SuggestionOptions();
$options->setAccuracy(0.4);
$options->setPageSize(5);
$options->setDistance(StringDistanceTypes::jaroWinkler());
$options->setSortMode(SuggestionSortMode::popularity());

/** @var array<SuggestionResult> $suggestions */
$suggestions = $session
    ->query(Employee::class, Employees_ByFullName::class)
    ->suggestUsing(function($builder) use ($options) {
        $builder->byField("FullName", "johne")
            ->withOptions($options);
    })
    ->execute();
// Query for terms from field 'Name' that are similar to 'chaig'
from "Products"
select suggest(Name, "chaig")

Suggest terms - for multiple terms

private int $pageSize = 15;
private ?StringDistanceTypes $distance = null;
private float $accuracy = 0.5;
private ?SuggestionSortMode $sortMode = null;

public function __construct()
{
    $distance = StringDistanceTypes::levenshtein();
    $sortMode = SuggestionSortMode::popularity();
    ...
}

// getters and setters for fields listed above
$suggestionWithTerm = new SuggestionWithTerm("FullName");
$suggestionWithTerm->setTerm("johne");

/** @var array<SuggestionResult> $suggestions */
$suggestions = $session
    ->query(Employee::class, Employees_ByFullName::class)
    ->suggestUsing($suggestionWithTerm)
    ->execute();
// Query for terms from field 'Name' that are similar to 'chaig' OR 'tof'
from "Products" select suggest(Name, $p0)
{ "p0" : ["chaig", "tof"] }

The auto-index terms in Studio

Based on the Northwind sample data, these are the terms generated for index Auto/Products/ByName:

Figure 1. Auto-index terms

Terms generated for index Auto/Products/ByName

  1. The field name - derived from the document field that was used in the dynamic-query.
    In this example the field name is Name.

  2. The terms generated from the data that the Products collection documents have in their Name field.

Syntax

Suggest using:

/**
 * Usage:
 *   - suggestUsing(SuggestionBase $suggestion);
 *   - suggestUsing(Closure $suggestionBuilder);
 *
 * @param SuggestionBase|Closure|null $suggestionOrBuilder
 * @return SuggestionDocumentQueryInterface
 */
public function suggestUsing(null|SuggestionBase|Closure $suggestionOrBuilder): SuggestionDocumentQueryInterface;
Parameter Type Description
$suggestionOrBuilder SuggestionBase An instance of SuggestionBase.
Defines the type of suggestion requested.
$suggestionOrBuilder Closure Builder with a fluent API that constructs a SuggestionBase instance.

Builder operations:

/**
 * Usage:
 *   - byField("fieldName", "term");
 *   - byField("fieldName", ["term1", "term2"]);
 */
function byField(?string $fieldName, null|string|StringArray|array $terms): SuggestionOperationsInterface;

function withOptions(?SuggestionOptions $options): SuggestionOperationsInterface;
Parameter Type Description
$fieldName ?string The index field in which to search for similar terms
$terms null
string
StringArray
array
List of terms to get suggested similar terms for
$options ?SuggestionOptions Non-default options to use in the operation (optional)

Suggestions options:

/**
 * Usage:
 *   - byField("fieldName", "term");
 *   - byField("fieldName", ["term1", "term2"]);
 */
function byField(?string $fieldName, null|string|StringArray|array $terms): SuggestionOperationsInterface;

function withOptions(?SuggestionOptions $options): SuggestionOperationsInterface;
Option Type Description
$pageSize int Maximum number of suggested terms to return
$distance ?StringDistanceTypes String distance algorithm to use
$accuracy float Suggestion accuracy
$sortMode ?SuggestionSortMode Order to return results by