Reputation: 11
I have an application that I inherited (using Sitecore CMS). We just recently upgraded Sitecore which required us to use a more recent version of Lucene.Net. Some of our old code broke. Problem is, I can't quite figure out what the code was trying to do. I'm not familiar with Lucene queries at all. In particular, I know that our RangeQueries have to now be TermRangeQueries, but I'm stuck when it comes to re-writing this code because I can't find an alternative for the BooleanQuery and it won't accept a TermRangeQuery as an input.
BooleanQuery lQuery = new BooleanQuery();
lQuery.Add(new TermQuery(new Term("_shorttemplateid", string.Format("{0}", ShortID.Encode(templateId).ToLowerInvariant()))),
Lucene.Net.Search.Occur.MUST);
if (string.IsNullOrEmpty(endDateItemFieldName))
{
lQuery.Add(
new RangeQuery(
new Term(startDateItemFieldName, startDateTime),
new Term(startDateItemFieldName, endDateTime), true),
Lucene.Net.Search.Occur.MUST);
}
else
{
lQuery.Add(
new RangeQuery(
new Term(startDateItemFieldName, startDate.ToString(DATE_TIME_FORMAT)),
new Term(startDateItemFieldName, string.Format("{0}{1}", endDate.ToString("yyyyMMdd"), endTimeStamp)), true),
Lucene.Net.Search.Occur.SHOULD);
lQuery.Add(
new RangeQuery(
new Term(endDateItemFieldName, startDate.ToString(DATE_TIME_FORMAT)),
new Term(endDateItemFieldName, string.Format("{0}{1}", endDate.ToString("yyyyMMdd"), endTimeStamp)), true),
Lucene.Net.Search.Occur.MUST);
}
Upvotes: 0
Views: 369
Reputation: 2422
First, take some time to read how the new Search API with Sitecore 7+ works:
Second, To rewrite your code in your example, create the following:
public class CustomSearchResult : Sitecore.ContentSearch.SearchTypes.SearchResultItem
{
[IndexField("START DATE FIELD NAME")]
public virtual DateTime EndDate {get; set;}
[IndexField("END DATE FIELD NAME")]
public virtual DateTime StartDate {get; set;}
}
Now, You can perform your search as follow:
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.Linq;
using Sitecore.ContentSearch.SearchTypes;
using Sitecore.ContentSearch.Linq.Utilities
using (var context = ContentSearchManager.GetIndex("sitecore_web_index").CreateSearchContext())
{
var results = context.GetQueryable<CustomSearchResult>().Where(i => i.TemplateId == Sitecore.Data.ID.Parse("TEMPLATE GUID") && i.StartDate > StartDateObject && i.EndDate < EndDateObject).GetResults().Hits.Select(i => i.Document.GetItem()).ToList();
return results;
}
Please note that StartDateObject and EndDateObject should be of type DateTime.
Hope this helps.
Upvotes: 0
Reputation: 13141
The code from your example is building a Lucene query using the following logic:
Pseudo-code:
Match all documents
That have a specific template ID
AND
IF an endDateItemFieldName is present
The start date must be between date X and Y
ELSE
The start date can be between date X and Y
But the end date must be between date X and Y
Behind the scenes, this results in a Lucene query that looks something similar to this:
+_shorttemplateid:3f2504e04f8941d39a0c0305e82c3301 start:[20020101 TO 20030101] +end:[20020101 TO 20030101]
In Sitecore 7+, much of the "Luceneness" has been abstracted away and is generated for you by a LINQ search provider. This allows you to switch between search implementations (for example, Solr) without any substantial refactoring of your code. Because LINQ is so widely known, working with the LINQ provider is often much easier for developers to grasp.
Here is an equivalent search query using the new LINQ provider.
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.Converters;
using Sitecore.ContentSearch.SearchTypes;
using System;
using System.ComponentModel;
namespace YourNamespace
{
public class DateSearchResultItem : SearchResultItem
{
[IndexField("startdate"), TypeConverter(typeof(IndexFieldDateTimeValueConverter))]
public DateTime StartDate { get; set; }
[IndexField("enddate"), TypeConverter(typeof(IndexFieldDateTimeValueConverter))]
public DateTime EndDate { get; set; }
}
}
And an example usage:
ISearchIndex index = ContentSearchManager.GetIndex("sitecore_web_index");
using (var context = index.CreateSearchContext())
{
var results = context.GetQueryable<DateSearchResultItem>()
.Where(item => item.TemplateId == new ID(templateId));
if (String.IsNullOrEmpty(endDateItemFieldName))
{
results = results
.Where(item => item.StartDate >= startDateTime)
.Where(item => item.StartDate <= endDateTime);
}
else
{
results = results
.Where(item => item.EndDate >= startDateTime)
.Where(item => item.EndDate <= endDateTime);
}
var compiledQuery = results.GetResults();
int totalMatches = compiledQuery.TotalSearchResults;
foreach (var hit in compiledQuery.Hits)
{
Item item = hit.Document.GetItem();
}
}
Upvotes: 1