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();

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.