目前,我正在一个项目中实施Sitecore 7.0 Update 2
在我的数据模板中,我有一个名为“开始日期”和另一个“结束日期”的字段。创建这两个字段的类型为“日期”(不是日期时间)。因此,当我编辑和创建项目时,它显示了一个日期选择器,并且我提交了一些内容为虚拟内容,并且上个月和当月的开始日期和结束日期为日期的日期。
我要实现的是在选定的月份内获取所有项目。我的方法包含一个月份和年份整数作为参数。这应该控制项目的开始和结束日期,该日期应从Lucene sitecore_master_index获取。Sitecore的Date字段的原始值是ISO datetime字符串。
因此,这是我尝试从该选定月份中获取所有项目的查询。
private void GetItems(int month, int year)
{
using (
IProviderSearchContext context =
ContentSearchManager.
GetIndex("sitecore_master_index").CreateSearchContext())
{
List<EventSearchResultItem> allEvents = context.GetQueryable<EventSearchResultItem>(new CultureExecutionContext(Sitecore.Context.Language.CultureInfo))
.Where(s =>
s.TemplateId == this.EventTemplateID &&
((s.BeginDate.Month == month && s.BeginDate.Year == year) || (s.EndDate.Month == month && s.EndDate.Year == year))
)
.ToList();
}
}
有了这个Where语句,我希望将Events-template的所有项目返回应该包含该月内日期的某个位置。但是它返回一个空的结果集。缺点是我无法调试Lamba表达式,因此不幸的是我不知道该范围的值。但是在1年和9999年之间不是:) IQueryable执行查询并返回了某些内容后,列表中的对象包含属性的正确DateTime。因此,它将字段正确地从索引映射到属性。另外,如果我删除了日期检查,那么只有TemplateID检查才是where-子句,它将返回结果。但是,即使将BeginDate与DateTime.MinValue和DateTime.MaxValue进行比较也不会返回任何内容。
它使用了我为此创建的POCO类EvenSearchResultItem。在此类中,我已将字段映射到属性,并添加了TypeConverter将其转换为DateTime。至少应该...
public class EventSearchResultItem : SearchResultItem
{
[TypeConverter(typeof(IndexFieldDateTimeValueConverter))]
[IndexField("__begin_date")]
public DateTime BeginDate { get; set; }
[TypeConverter(typeof(IndexFieldDateTimeValueConverter))]
[IndexField("__end_date")]
public DateTime EndDate { get; set; }
}
在Sitecore.ContentSearch.Lucene.DefaultIndexConfiguration.config中,我在-tag中添加了该字段(也尝试了-tag,但结果没有太大不同)。看到:
<field luceneName="__begin_date" storageType="yes" indexType="tokenized" format="yyyyMMdd">Begin Date</field>
<field luceneName="__end_date" storageType="yes" indexType="tokenized" format="yyyyMMdd">End Date</field>
因此,在Luke(用于查看Lucene索引内容的Java应用程序)中,在重新索引后,该字段出现并包含该项目的给定日期(yyyyMMdd> 20140214)。就像其他日期字段一样,例如__smallCreatedDate。
我可以通过将查询修改为:
List<EventSearchResultItem> allEvents = context.GetQueryable<EventSearchResultItem>()
.Where(s =>
(s["Begin Date"].StartsWith(string.Concat(year, month.ToString("00"))) || s["End Date"].StartsWith(string.Concat(year, month.ToString("00"))))
)
.ToList();
这是Stack Overflow另一个问题的解决方案。但我不认为这是最佳实践和可靠的方法。不幸的是,谷歌没有其他选择。我猜像我想像的那样可能吗?
有没有人有过从IQueryable过滤DateTime上的Lucene结果的经验?可以指出正确的方向吗?
尝试以下方法:
private void GetItems(int month, int year)
{
DateTime startDate = new DateTime(year,month,1);
DateTime endDate = new DateTime(year,month, DateTime.DaysInMonth(year, month));
using ( IProviderSearchContext context = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
List<EventSearchResultItem> allEvents = context.GetQueryable<EventSearchResultItem>(new CultureExecutionContext(Sitecore.Context.Language.CultureInfo))
.Where(s =>
s.TemplateId == this.EventTemplateID &&
((s.BeginDate >= startDate) || (s.EndDate <= endDate))
)
.ToList();
}
}
编辑:只是为了解释为什么您的方法行不通,当lucene索引任何日期字段时,它被索引为数字,格式将为“ yyyyMMdd”,例如2014年2月18日被索引为20140218,因此您可以看到它被存储为一个整数,并且年,月和日位于同一字段中,因此您无法与仅年或仅月等进行比较。
现在在Sitecore linq中,如果要查询日期字段,则必须与“ DateTime”类型进行比较,Sitecore知道在将日期时间对象传递给Lucene之前,必须将其转换为“ yyyyMMdd”格式。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句