Full Text Search
The search engine capabilities in LightSpeed provide an easy to use free text search implementation that is database engine independent. It provides developers a mechanism to perform Google-style queries and have them match any entities within a defined scope – for example, provide any entity that has the word ‘car’ in it.
To implement full text search in your LightSpeed application you need to use a search provider. Out of the box, LightSpeed ships with a single search provider which is built on top of the open-source Lucene project. Lucene provides a very high performance and scalable search infrastructure. Developers can plug in their own search provider by implementing the ISearchEngine interface.
To use a full text search you first need to instruct LightSpeed to use the search engine and where it can store the search index on disk. This is done via configuration of the LightSpeedContext by either XML configuration file or in code.
Configuring the default search provider for LightSpeed in the config file |
<add name="Test" |
Make sure that the search engine file location directory is writable by your application process as it will be written to as new entities are saved.
Indexing Data
LightSpeed does not index the entire database – it will only index data on entities that you care about. To enable indexing, select each of the properties that you want to include in the search index and set their Include in Full Text Index option to true. To do this in hand coded entities, apply IndexedAttribute to the fields:
Instructing LightSpeed to store a value in the search index |
[Indexed] |
In advanced scenarios you can override the Entity.SearchData method to provide custom indexing data to be indexed. Note that you will still need to set Include in Full Text Index on one of the entity’s properties (or apply IndexedAttribute to one of its fields) to notify LightSpeed that you wish the entity to be indexed; however, when you override Entity.GetSearchData LightSpeed will use your custom implementation instead of getting indexing data from the attributed field.
Overriding the GetSearchData() method to combine entity data for one entity |
protected override string GetSearchData() |
Overriding the GetSearchData method provides a powerful mechanism for collapsing indexed data into one entity. For example, when searching for a Car you may want to include engine details. These are stored in an Engine entity, but you can add them to the Car index data by returning them from Car’s GetSearchData method.
If updating the fields that are being indexed or overriding GetSearchData, be sure to call a Rebuild of your search index to ensure that the search engine index is up to date with your changes.
Building the Search Index
By default LightSpeed will update the search index when you call UnitOfWork.SaveChanges. The changes that have occurred as part of the save will be updated in the search index. However, if you are adding a search index to an existing database it’s important to rebuild the search index from the entire database, not just a single change set. LightSpeed provides the Rebuild method for rebuilding the entire search index. Call Rebuild with the types of entities that you want to have indexed.
Rebuilding the entire search index |
_context.SearchEngine.Rebuild(IsolationLevel.ReadCommitted, |
Rebuilding the search index should not be needed often. Calling Rebuild() can be an expensive operation, and for larger database solutions you may wish to use Lucene outside of the LightSpeed framework to achieve the best performance.
Performing Searches
Performing searches using LightSpeed is done with a LightSpeed query object. This first example demonstrates searching for a comment with the word “video” in it.
Basic search over one entity type |
Query query = new Query(); |
Searching with LightSpeed is not limited to only returning one type of entity. The next example demonstrates searching for comments and tags at the same time.
Basic search over several entity types |
Query query = new Query(); |
You can combine a full text search and a normal SQL query to limit the text search.
Advanced search combining normal query and search index |
using (var unitOfWork = _context.CreateUnitOfWork()) |
Advanced Operator Support
As LightSpeed is using Lucene by default as a search engine developers can use any of the advanced operators that Lucene supports by specifying them in the SearchQuery string.
Further Search Reading
If you are developing a significant solution with LightSpeed and working with Lucene for search, we recommend that you read about Lucene and understand how to configure and operate it for the best performance. See the Lucene Web site for more information.