Lucinq Features – Date range searching

Pulling items by date or date range out of Lucene is quite a useful process. To do it accurately, we need to store the date values in a field that can be parsed appropriately. In Lucinq, our fluent Lucene wrapper, we currently achieve this by converting the DateTime value into an integer using the ticks property. This has a resolution down to 100ns which should be enough for anyones needs!

Using this, it allows us to create a range based search by comparing the ticks values between two dates. Then, for Lucene this is a simple integer comparison (taken directly from our test suite):

LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory);

IQueryBuilder queryBuilder = new QueryBuilder();
DateTime february = DateTime.Parse("01/02/2013");
DateTime end = DateTime.Parse("28/02/2013");

queryBuilder.Setup(
	x => x.WildCard(BBCFields.Description, "food", Matches.Always),
	x => x.Filter(DateRangeFilter.Filter(BBCFields.PublishDateObject, february, end))
);

ILuceneSearchResult result = luceneSearch.Execute(queryBuilder);
List<NewsArticle> data = Mapper.Map<List<Document>, List<NewsArticle>>(result.GetTopItems());

This is similar to the way you’d think about doing it in SQL. Behind the scenes, SQL Server stores datetime values with very high precision.

Its worth noting that we’ve used the date based range as a filter in this example. We can also apply a date range directly and have it work like so:

LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory);

IQueryBuilder queryBuilder = new QueryBuilder();
DateTime month = DateTime.Parse("01/02/2013");

queryBuilder.Setup(
	x => x.DateRange(BBCFields.PublishDateObject, month, month.AddDays(28)),
	x => x.WildCard(BBCFields.Description, "food")
);

ILuceneSearchResult result = luceneSearch.Execute(queryBuilder);
List<NewsArticle> data = Mapper.Map<List<Document>, List<NewsArticle>>(result.GetTopItems());

I think this is a good example of picking the correct field type for the job. By avoiding using a string we gain a lot more relevant operations without issues in casting the data. A case study for this would be a project I completed some time ago where cooking times needed to act as filters for a search. We were unable to achieve consistent results until the cooking time was stored as an integer value rather than a string. Which is something you would expect in code but potentially neglect in a search index.

Resources

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s