【问题标题】:Query lucene index against IEnumerable field针对 IEnumerable 字段查询 lucene 索引
【发布时间】:2015-10-23 11:20:30
【问题描述】:

我在 Lucene 索引中有一组课程,其中包含零个或多个可用日期。我正在尝试查询索引,以便返回任何可用日期介于从/到日期之间的课程。

使用我的 CourseSearchResultItem 中的属性将该字段作为 DateTime 对象的集合返回

 public class CourseSearchResultItem : SearchResultItem
 {
     [IndexField("availabledatesforcourse")]
     public IEnumerable<DateTime> AvailableDatesForCourse { get; set;}
 }

正在构造的查询使用以下代码:

 if (courseSearchCriteria.FromDate.HasValue)
     query = query.Where(c => c.AvailableDatesForCourse.Any(d => d >= courseSearchCriteria.FromDate.Value));

 if (courseSearchCriteria.ToDate.HasValue)
     query = query.Where(c => c.AvailableDatesForCourse.Any(d => d <= courseSearchCriteria.ToDate.Value));

运行它会产生以下异常:

Any 调用中不支持的 lambda。使用的表达式 'd => (d >= Value (RCS.Web.Areas.RcsEng.Controllers.CoursesApiController +c__DisplayClass10_0).courseSearchCriteria.FromDate.Value)'

我知道这是由于 Sitecore.Linq Any() 方法的限制,但我不确定如何重新创建所需的功能。有没有人有类似的问题可以阐明解决方案?

【问题讨论】:

标签: c# linq sitecore lucene.net sitecore8


【解决方案1】:

试试下面的。

将您的班级更改为如下所示:

 public class CourseSearchResultItem : SearchResultItem
 {
     [IgnoreIndexFieldAttribute]
     [IndexField("availabledatesforcourse")]
     public DateTime AvailableDatesForCourse { get; set;}
 }

现在将您的查询更改为如下所示:

if (courseSearchCriteria.FromDate.HasValue)
     query = query.Where(c => c.AvailableDatesForCourse == courseSearchCriteria.FromDate.Value);

if (courseSearchCriteria.ToDate.HasValue)
 query = query.Where(c => c.AvailableDatesForCourse == courseSearchCriteria.ToDate.Value));

这种语法适用于在搜索文档中多次存储的值(例如,_path 字段,它分别存储所有父项的 GUID)。它将由 ContentSearch API 翻译成查询 Lucene 可以理解的,是这样的:

AvailableDatesForCourse:<your date>

更新 [IgnoreIndexFieldAttribute] 将防止在 ContentSearch 为您的课程提供水合物时出现映射错误,但不会阻止在查询中使用该字段。我写了一个 LinqScratchPad Gist 来说明这一点,您可以通过粘贴或使用 URL Fetch 按钮将其加载到 /sitecore/admin/LinqScratchPad.aspx 的 Sitecore LinqScratchPad 中。这将查找名称中包含“Media Item”的所有项目:

【讨论】:

  • 感谢 Dan,查询现在返回的课程的可用日期介于 From 和 To 日期之间,但是,当尝试将搜索结果中的对象映射回 CourseSearchResultItem 类时,它似乎是试图将字符串数组映射到单个字符串对象。这将导致以下结果:无法将索引文档字段映射到 CourseSearchResultItem 类型的属性“AvailableDateForCourse”:无法将 System.String[] 类型的值转换为目标类型 System.DateTime:无法转换类型为“System”的对象.String[]' 输入'System.String'。
  • 更新了关于 IgnoreFieldAttribute 讨论的答案,这应该可以帮助您解决这个问题。
  • 嗨,Dan,使用 IgnoreIndexField(sitecore 8 版本)来防止映射回可用日期是一种享受。感谢您的帮助 - 非常感谢。
【解决方案2】:

我遇到了同样的问题,并按照 Dan 的步骤帮助我找到了解决方案。我遇到的问题是 SitecoreContentSearch 正在创建 Solr 无法解析的查询。我将 linq 查询更新为:

if (courseSearchCriteria.FromDate.HasValue && courseSearchCriteria.ToDate.HasValue)
query= query.Where(x => x.AvailableDatesForCourse.Between(courseSearchCriteria.FromDate.Value,courseSearchCriteria.ToDate.Value,Inclusion.Both));

这应该会创建一个如下所示的查询:

availabledatesforcourse:[2018-07-13T15:48:42.975Z TO 2021-07-13T15:48:43.023Z]

这使我可以在日期列表中搜索任何属于此范围的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 2012-09-04
    • 2017-01-29
    • 1970-01-01
    相关资源
    最近更新 更多