Getting Started with IPWorksSearch
Requirements: IPWorks Search
Introduction
IPWorks Search provides a suite of easy-to-use components designed to search, create, and manage Lucene search indexes. This article covers indexing simple documents with the Indexer component and searching for them with the Search component.
Contents
Indexer
The Indexer component manages Lucene 4.8 search indexes. It provides a simple way to create, update, and delete documents in a search index.
Preparing the Search Index
To get started with the Indexer component, first set the IndexPath property to specify the location of the search index. If the specified location does not point to a pre-existing index, the component will automatically create a new one and store it in the specified directory. Once the property is set, call the OpenIndex method to load the search index.
It is important to note that the OpenIndex method will load a snapshot of the index at the time it was opened. OpenIndex can be called multiple times to reload the index and reflect its latest changes in indexing operations.
indexer.IndexPath = "\\PATH\\TO\\INDEX"; // The path to the search index
indexer.OpenIndex(); // Load the index
Creating Documents
The search index consists of documents, which are flexible structures optimized for search operations. Each document is composed of distinct fields that have a name and textual data.
The first step in creating a document is to add its fields to the Fields collection. Each field has a name, storage option, type, text content, and analyzer.
The following example shows how to create a simple document field and add it to the Fields collection:
string name = "title"; // The identifier of the field
bool store = true; // Determines if the field's contents should be stored in the index
int type = (int)TFieldTypes.ftText; // The type of data the field contains
string text = "Getting started with IPWorksSearch"; // The text content of the field
int analyzerType = (int)TSearchIndexAnalyzerTypes.atStandard; // Controls the text processing performed on the field's text content
indexer.AddDocumentField(name, store, type, text, analyzerType); // Add the field to the Fields collection
After populating the Fields collection with the desired fields, the IndexDocument method can be called to create a new document from these fields and add it to the search index.
indexer.IndexDocument(); // Add a document with the added field to the search index
Deleting Documents
Documents can be deleted from the index via the Delete method. The method requires the name and value of a field used to identify the documents that will be deleted.
The following example shows how to delete every document in the index that has a field named "title" and a value of "Getting started with IPWorksSearch":
string name = "title"; // The name of the field used to identify the documents to delete
string text = "Getting started with IPWorksSearch"; // The text content of the field used to identify the documents to delete
indexer.Delete("title", "Getting started with IPWorksSearch");
Saving the Search Index
After making changes to the index, call the CloseIndex method to save the changes.
indexer.CloseIndex();
Search
The Search component retrieves documents from a Lucene search index. It provides a simple way to perform search operations using the full Lucene query syntax. Additionally, it provides support for advanced search queries, pagination, term highlighting, and more.
Preparing the Search Index
To begin using the Search component, first set the IndexPath property to the location of the search index that will be searched and call the OpenIndex method. This will load the index for searching.
search.IndexPath = "\\PATH\\TO\\INDEX"; // Specify the path to the search index
search.OpenIndex(); // Load the index
Searching the Index
To begin a search operation, call the SimpleSearch method. This will prompt the component to find any documents in the index with fields that match the specified search query. The QueryText parameter specifies the text to look for in the index. This value fully supports the Lucene 4.8 query syntax, as defined in the Lucene query parser documentation.
The following example shows how to search the index for any documents with text that matches the expression "Getting started":
// Search the index for documents that have text matching the expression "Getting started"
search.SimpleSearch("Getting started");
Search Results
After calling the SimpleSearch method, the SearchResult event will fire for each document in the index that matches the search query. Within this event, the ResultFields collection and GetResultField method can be used to get information about the fields in these documents.
search.OnSearchResult += (s, e) =>
{
// Display the title of the current search result
Console.WriteLine("title: " + search.GetResultField("title"));
foreach (ResultField field in search.ResultFields) // Contains every field in the current search result
{
// Display the name and text content of every field in the current search result
Console.WriteLine(field.Name + ": " + field.Text);
}
};
Highlighting Relevant Terms
The Highlight method can be called from within the SearchResult event to retrieve the most relevant text snippet of a field from a search result. The most relevant terms within this snippet will be highlighted using the HTML tag specified in the HighlightTag property.
search.HighlightTag = "<em>"; // Tell the component we want to highlight each relevant term with <em> tags
search.OnSearchResult += (s, e) =>
{
// If the current search result has a field named "content" with
// a value of "Getting started with IPWorksSearch", this method will return
// "<em>Getting started</em> with IPWorksSearch"
string highlight = search.Highlight("content");
Console.WriteLine("\t\t-> Highlight: " + highlight);
};
Extended Search
For more complex search operations, the Search component supports creating boolean queries via the ExtendedSearch method. These queries provide more direct control over search operations and enable searching for documents that must match multiple criteria.
To begin a boolean search, use the AddQuery method to add queries to the Queries collection. Each query specifies the field to search, the value to look for, the type of content to look for, and how the query relates to other queries.
// Add a term query to search for documents containing "nsoftware" in the "company" field
search.AddQuery("company", "nsoftware", (int)TQueryTypes.qtTerm, (int)TOccurTypes.otMust);
// Add a phrase query to search for documents containing the phrase "software development" in the "content" field
search.AddQuery("content", "software development", (int)TQueryTypes.qtPhrase, (int)TOccurTypes.otMust);
After populating the Queries collection with search queries, call the ExtendedSearch method to start the boolean search operation. This will combine all of the queries added to the Queries collection. The SearchResult event will then fire for each document in the index that matches the combined queries.
search.ExtendedSearch();
Pagination
The component handles pagination automatically. After performing a search operation with SimpleSearch or ExtendedSearch, the HasMorePages property will indicate whether more pages of results are available. A subsequent call to the same method will retrieve the next page of results if HasMorePages is true.
// Search the index until there are no more pages left
do {
search.ExtendedSearch();
} while (search.HasMorePages);
Closing the Index
After completing the search operations, call the CloseIndex method to unload the index.
search.CloseIndex();
We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at kb@nsoftware.com.