Prefix Queries

Prefix queries allow you to add a ‘starts with’ predicate to your query. A common example is that of a category based search. Here, the category field contains paths:

        /root/cata/catb/
        /root/cata/catb/catc

And then you use the prefix as prefix with ‘/root/cata/catb’ to search all the data in ‘catb’ and below.

The integration tests do something similar using the title of the news stories. Some of these begin with ‘in pictures:’ and we want to use that as an additional restriction on the search results:

        LuceneSearch luceneSearch = new LuceneSearch(IndexDirectory);

        IQueryBuilder queryBuilder = new QueryBuilder();

        // The prefix query needs to work against a field that hasn't been tokenised/analysed to work.
        queryBuilder.Setup(
            x => x.PrefixedWith(BBCFields.Sortable, QueryParser.Escape("in pictures"), Matches.Always)
        );

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

        WriteDocuments(data);

        Console.WriteLine("Searched {0} documents in {1} ms", result.TotalHits, result.ElapsedTimeMs);
        Console.WriteLine();

        Assert.AreNotEqual(0, result.TotalHits);

This also supports filtering, searching and collectors. The sample below shows this:

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

        // The prefix query needs to work against a field that hasn't been tokenised/analysed to work.
        queryBuilder.Setup(
            x => x.PrefixedWith(BBCFields.Sortable, QueryParser.Escape("in pictures"), Matches.Always),
            x => x.WildCard(BBCFields.Description, "images", Matches.Always),
            x => x.Filter(DateRangeFilter.Filter(BBCFields.PublishDateObject, february, end))
        );

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

        WriteDocuments(data);

        Console.WriteLine("Searched {0} documents in {1} ms", result.TotalHits, result.ElapsedTimeMs);
        Console.WriteLine();

        Assert.AreNotEqual(0, result.TotalHits);
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