【发布时间】:2014-06-19 07:58:16
【问题描述】:
我有一个非常奇怪的问题,我无法理解。也许有人可以指出我做错了什么。
基本上,我只是尝试使用 Linq to Sitecore 搜索项目。
所以,我的课程看起来像(我也在使用玻璃)
[SitecoreType(TemplateId = "{TEMPLATE_GIUD}")]
public class MyMappedClass : SharedFieldClass
{
[SitecoreField(FieldName = "mylist")]
public virtual IEnumerable<SharedFieldClass> MyMultilistField { get; set; }
[SitecoreField(FieldName = "field1")]
[IndexField("field1")]
public virtual MyKeyValue field1 { get; set; }
}
[SitecoreType]
public class MyKeyValue
{
public virtual Sitecore.Data.ID Id {get;set;}
public virtual string MyValue{get;set;}
}
所以当我执行以下查询时,它会按预期工作。
var results = context.GetQueryable<SearchResultItem>()
.Where(c => ((string)c["field1"]) == "{GUID}").GetResults();
但是,当我执行以下操作时,它会返回 0 结果。
List<MyMappedClass> results = context.GetQueryable<MyMappedClass>()
.Where(c => c.field1.MyValue == "{GUID}").ToList();
我已阅读 this link 。我已经按照 here 描述的第二个流程让 Glass 与 Sitecore7 Search 一起工作(“SharedFieldClass”包含所有基本索引字段)。
这是一个非常明显的场景,我相信很多人已经这样做了,而我在这里做了一些愚蠢的事情。
提前致谢。
/## 编辑##/
好的,所以我对此进行了更多挖掘。不确定这是否是 ContentSearch/Luncene.NET API 中的错误,或者我遗漏了一些东西,但似乎 here 发布的内容可能不是 TRUE,如果您有一个复杂的字段类型(您会这样做),您无法使用针对 Lucene 的映射类。 (不确定 Solr 是否也是这种情况)。如果您正在对字符串和 int 等简单类型进行搜索,那么它就像一个魅力。
这是我的发现:
- 在为 contentsearch 启用 DEBUG 和 LOG 后,我发现如果我像这样查询
context.GetQueryable<MyMappedClass>().Where(c => c.field1.MyValue == "{GUID}"),它会被翻译成DEBUG Executing lucene query: field1.value:7e9ed2ae07194d83872f9836715eca8e,并且在名为“field1.value”的索引中没有这样的东西,因此查询不会不返回任何东西。索引的名称实际上只是“field1”。 这是一个错误吗?? - 但是,像
context.GetQueryable<SearchResultItem>() .Where(c => ((string)c["field1"]) == "{GUID}").GetResults();这样的查询可以工作,因为它会被翻译成"DEBUG Executing lucene query: +field1:7e9ed2ae07194d83872f9836715eca8e"。 -
我也确实在我的映射类中编写了一个方法,如下所示:
public string this[string key] { get { return key.ToLowerInvariant(); } set { } }
这让我可以使用 MyMappedClass 编写以下查询。
results2 = context.GetQueryable<MyMappedClass>().Where(c => c["filed1"]== "{GUID}").ToList();
这返回了预期的结果。 BUT MyMappedClass 中的字段值没有被填充(实际上它们都是空的,除了在填充的文档中填充的核心/共享值,如 templateid、url 等)。所以结果列表几乎没有用。我可以对所有这些进行循环并手动获取填充的值,因为我有 itemid。但是想象一下大型结果集的成本。
最后我这样做了:
<fieldType fieldTypeName="droplink" storageType="YES" indexType="TOKENIZED" vectorType="NO" boost="1f" type="System.String" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider" />
因此,在使用“IndexViewer2.0”的 lucene 查询中返回了填充的“field1”和 itemid。 但是这对于 MyMappedClass 也失败了,因为文档中“field1”的值是一个 System.string .. 但它在 MyMappedClass SO 中被映射为“MyKeyValue”它抛出以下异常
Exception: System.InvalidCastException
Message: Invalid cast from 'System.String' to 'MyLib.MyKeyValue'.
所以,最大的问题是: 如何使用酷炫的 ContentSearch API 使用他/她的映射类进行查询?
【问题讨论】:
-
尝试将 ContentSearch.EnableSearchDebug 设置为 true 然后将 logger "name="Sitecore.Diagnostics.Search" 级别更改为 DEBUG,这将记录您翻译的 lucene 查询,您可以检查有什么问题它
-
嗨@AhmedOkour,感谢您的提示。这有助于进一步挖掘。请参阅我编辑的部分。
-
我遇到了完全相同的问题 - 没有找到任何其他尝试这样做的人的参考资料。目前,我正在使用自定义 TypeConverter,它可以填充属性,但它没有 .Where 过滤语法起作用。
-
@tomunderhill 在其中一个答案中查看我的工作。我没有将其标记为“正确答案”,因为我想先尝试 Michael Edward 的解决方案,在这种情况下,我仍然面临一些关于 contentsearchindex(web) 中填充的索引值的问题。所以基本上我现在面临的是我在我的真实代码中的 where 子句中放置了 2 个条件。其中一个字段已填充,但另一个字段未填充,即使它们都是 droplink 字段类型(我猜这与索引本身有关......有什么想法吗?)。很快就会在这里发布我的发现。
标签: linq sitecore sitecore7 linq-query-syntax glass-mapper