我有一个非常奇怪的问题,我无法解决。也许有人可以指出我做错了什么。
基本上,我只是想使用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();
我已阅读此链接。而且,我遵循了此处描述的第二个过程,以使Glass与Sitecore7搜索一起使用(“ SharedFieldClass”包含所有基本索引字段)。
这是一个非常明显的场景,我敢肯定很多人已经做到了,而我在这里做的事情很愚蠢。
提前致谢。
/ ##编辑## /
好吧,我对此做了更多的挖掘。不知道这是不是ContentSearch / Luncene.NET API中的错误,还是我错过了一些东西,但似乎这里发布的内容可能不是TRUE,并且如果您具有复杂的字段类型(将要使用),则无法使用映射的类进行查询反对Lucene。(不确定Solr是否也是这种情况)。如果您要搜索像string和int这样的简单类型,那么它就像一个符咒。
所以这是我的发现:
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();
这返回了预期结果。但是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太为“字段1”的文档中的值以System.String ..但它是在MyMappedClass映射为“MyKeyValue” SO它抛出异常下方
Exception: System.InvalidCastException
Message: Invalid cast from 'System.String' to 'MyLib.MyKeyValue'.
因此,最大的问题是:一个查询如何使用很酷的ContentSearch API使用其映射类进行查询?
您可以为lucene创建一个自定义字段映射器,该映射器将从索引中的Guid转换为玻璃模型。我破解了这个,但尚未测试:
public class IndexFieldDateTimeValueConverter : TypeConverter
{
public Type RequestedType { get; set; }
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
var config = Glass.Mapper.Context.Default.GetTypeConfiguration<SitecoreTypeConfiguration>(sourceType, true);
if (config != null)
{
RequestedType = sourceType;
return true;
}
else
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
return true;
else
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var scContext = new SitecoreContext();
return scContext.CreateType(RequestedType, scContext.Database.GetItem(value.ToString()),true, false, new Dictionary<string, object>());
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
var config = Glass.Mapper.Context.Default.GetTypeConfiguration<SitecoreTypeConfiguration>(value.GetType(), true);
ID id =config.GetId(value);
return id.ToShortID().ToString().ToLowerInvariant();
}
我担心的是,ConvertFrom方法没有传递所请求的类型,因此我们必须将此属性存储为类,才能将其从CanConvertFrom方法传递给ConvertFrom方法。这使得此类不是线程安全的。
将此添加到sitecore配置的indexFieldStorageValueFormatter部分。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句