Searching

How to search against a LIFTI index

There are two ways to query a FullTextIndex, searching with a query string and executing a manually constructed Query.

Searching with text

index.Search("find something");

This approach uses the IQueryParser implementation configured for the index to parse the query text into a Query object, which is then executed.

The default IQueryParser that is configured against an index parses the LIFTI query syntax, which is a fairly flexible way of expressing a query. If you want to swap out this parser with a custom implementation, you can do so when building the index using WithQueryParser option.

Searching with a Query

You can manually construct a Query using any combination of IQueryParts, but take care to normalize any text to match in the same way that it has been indexed. You can do this using either the IIndexTokenizer for the index, or if specific tokenization rules have been configured for a field, then the tokenizer for that field:

var tokenizer = index.DefaultTokenizer;
var query = new Query(
    new AndQueryPart(
        new ExactWordQueryPart(tokenizer.Normalize("hello")), 
        new ExactWordQueryPart(tokenizer.Normalize("there"))));

Obtaining query execution plans

By specifying QueryExecutionOptions.IncludeExecutionPlan when searching, LIFTI will collect timing information during the execution of the various query parts:

index.Search("find something", QueryExecutionOptions.IncludeExecutionPlan);

This enables ISearchResults.GetExecutionPlan to return the actual execution plan for the query. If QueryExecutionOptions.IncludeExecutionPlan is not specified, GetExecutionPlan returns a placeholder execution plan.

See Understanding LIFTI query execution plans for more details.


The LIFTI Query Syntax

The default query parser for an index makes use of a powerful query syntax.

Query execution

LIFTI attempts to optimize the order that query parts are executed to make queries as efficient as possible.

Fuzzy Matching

Fuzzy matching provides a mechanism by which you can search for words that are close to a search term, in terms of the number of differences between them.

Simple Queries

When you want to keep your queries simple, always searching for documents containing all (or just some) search terms, you can configure an index to use the simple query parser.

Manually Constructing Queries

Instead of using a query parser to interpret your query, you can manually construct a Query object and execute it against the index.

Field Information

You can query the index to get information about the fields that have been indexed.

IndexNavigator

You can use an IndexNavigator to navigate the index character by character.

Understanding Query Execution Plans

LIFTI’s Query Execution Plan provides detailed insights into the execution of a query, including the order, timing, and the structure of the query parts.

Search Results

FullTextIndex<T>.Search returns ISearchResults<T>, which implements IEnumerable<SearchResult<T>> and provides other utilities for processing the matched search locations further.

Last modified February 23, 2024: Query execution plans (#111) (16dc5af)