Sitecore 6 Lucene Search: The most common queries

11 November 2013
Marek Musielak
Frink_Cognifide_2016_HeaderImages_0117

sitecore lucene search and indexing - queries examples

This blog post provides examples of most popular Lucene queries used while performing search in Sitecore 6 applications. If you need an introduction to Sitecore and Lucene you can find one in my other blog post: A quick guide how to setup the simplest Lucene search in Sitecore. And if the query you're looking for is not covered by this post do not hesitate to ask a question in a comment below this blog post.

There are lot of ways of using Lucene search in Sitecore. What I want to show you is a set of queries which I find the most popular. My application contains a very basic index configuration (same as in the post linked above). I've also added additional line to my configuration to add standard fields like __created or __updated to the fields indexed by Lucene (remember to rebuild index after this configuration is added).

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
 <sitecore>
  <settings>
   <setting name="Indexing.IndexStandardTemplateFields" value="true"/>
  </settings>
 </sitecore>
</configuration>
Whenever you have built a query and you need to get items based on that query, you can use following method to retrieve those:
public List<Item> GetItemsFromQuery(Query query)
{
	using (IndexSearchContext sc = 
	    SearchManager.GetIndex("Custom Index").CreateSearchContext())
	{
		// search items using query and checking maximum number of items
		TopDocs topDocs = sc.Searcher.Search(query, int.MaxValue);

		// read search hits from the found Lucene docs
		SearchHits searchHits = 
		    new SearchHits(topDocs, sc.Searcher.GetIndexReader());

		return searchHits
			// fetch all hits starting from the first one
			.FetchResults(0, int.MaxValue)
			// and retrieve Sitecore item for all of them
			.Select(r => r.GetObject<Item>()).ToList();
	}
}
The most popular case when you may want to use Lucene in Sitecore is when you need to get items which contain particular phrase in one of their fields. To retrieve them you can use TermQuery, e.g. for all items which contain ‘sample’ in their title use:
TermQuery byTermInTitleQuery = new TermQuery(new Term("title", "sample"));
and pass it as a parameter to GetItemsFromQuery method above. Similarly use
new TermQuery(new Term("__created by", "sitecore\\admin"))
to retrieve all items created by administrator or
new TermQuery(new Term("__workflow state", stateId.ToLower()))
to get all items in a particular workflow state. One thing you need to remember is that by default Sitecore crawls all fields converted to lowercase so you need to pass lowercase versions of those in your queries as well.

When you want to use Lucene to retrieve items based on the Checkbox field value, you can use TermQuery as well. Just remember that Sitecore stores not-checked state as empty value and checked state as '1' so use one of the queries below:
TermQuery neverPublishCheckedQuery = new TermQuery(new Term("__never publish", "1"));
TermQuery neverPublishNotCheckedQuery = new TermQuery(new Term("__never publish", ""));
If you need to find items by date range, e.g. created between some dates, you can use TermRangeQuery:
string createdFrom = DateUtil.ToIsoDate(new DateTime(2013, 10, 10));
string createdTo = DateUtil.ToIsoDate(new DateTime(2013, 11, 10));

new TermRangeQuery("__created", createdFrom, createdTo, true, false);
If you need items which fulfill one or another requirement you can add both of them to the BooleanQuery with Occur.SHOULD as a second parameter and use the parent boolean query to retrieve the items, e.g. if you want to get all the items either created or updated by admin, use:
TermQuery createdByAdminQuery = new TermQuery(new Term("__created by", "sitecore\\admin"));
TermQuery updatedByAdminQuery = new TermQuery(new Term("__updated by", "sitecore\\admin"));

BooleanQuery createdOrUpdatedByAdminQuery = new BooleanQuery();

createdOrUpdatedByAdminQuery.Add(createdByAdminQuery, 
    BooleanClause.Occur.SHOULD);

createdOrUpdatedByAdminQuery.Add(updatedByAdminQuery, 
    BooleanClause.Occur.SHOULD);

createdOrUpdatedByAdminQuery.SetMinimumNumberShouldMatch(1);

items = GetItemsFromQuery(createdOrUpdatedByAdminQuery);
You can build more and more complex combined queries just by adding them to another BooleanQuery, e.g. the query below will return all the items which contain 'sample' in their titles and are either edited or created by admin:
BooleanQuery combinedQuery = new BooleanQuery();

TermQuery titleQuery = new TermQuery(new Term("title", "sample"));

combinedQuery.Add(titleQuery, BooleanClause.Occur.MUST);
combinedQuery.Add(createdOrUpdatedByAdminQuery, BooleanClause.Occur.MUST);

items = GetItemsFromQuery(combinedQuery);

Those are queries which I find as most useful while using Sitecore with Lucene. You can find more query types in the Lucene.Net.Search namespace. If you have any questions or comments or you need a hand with building a query for what you need to get from Sitecore, do not hesitate to leave your comment below. And if you're interested in more information about Lucene and Sitecore, check out my other
Sitecore blog posts.

This information is based on an empty Sitecore 6.6 rev.130529 (Service Pack-1) solution without any modifications.