我有一个我继承的应用程序(使用Sitecore CMS)。我们刚刚升级了Sitecore,要求我们使用更新版本的Lucene.Net。我们的一些旧代码破了。问题是,我无法弄清楚代码试图做什么。我根本不熟悉Lucene的查询。特别是,我知道我们的RangeQueries现在必须是TermRangeQueries,但是在重写这段代码时我很困难,因为我找不到BooleanQuery的替代方案而且它赢了接受TermRangeQuery作为输入。
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);
}
答案 0 :(得分:1)
您的示例中的代码使用以下逻辑构建Lucene查询:
<强>的伪代码:强>
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
在幕后,这会产生类似于此的Lucene查询:
+_shorttemplateid:3f2504e04f8941d39a0c0305e82c3301 start:[20020101 TO 20030101] +end:[20020101 TO 20030101]
在Sitecore 7+中,很多&#34; Luceneness&#34;已被抽象出来并由LINQ搜索提供程序为您生成。这允许您在搜索实现(例如,Solr)之间切换,而无需对代码进行任何实质性重构。因为LINQ是如此广为人知,所以与LINQ提供程序一起工作通常更容易让开发人员掌握。
以下是使用新LINQ提供程序的等效搜索查询。
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; }
}
}
一个示例用法:
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();
}
}
答案 1 :(得分:0)
首先,花点时间阅读Sitecore 7+的新Search API的工作原理:
其次,要在示例中重写代码,请创建以下内容:
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;}
}
现在,您可以执行以下搜索:
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;
}
请注意 StartDateObject 和 EndDateObject 应为DateTime类型。
希望这有帮助。