我正在尝试包含相关文档(特定于Sitecore,Lucene文档是Item
),以便当Lucene索引为类型A的项创建文档时,它还将包含所有属性来自另一个项目B.
最终结果是,当用户搜索在项目B上找到的数据时,用户会对项目A进行命中。实际上,我想我正在尝试以编程方式“扩展”Lucene文档。
到目前为止,这是我的代码。我正在扩展索引器类并重写一个方法,我将项目B中的字段添加到项目A(上下文文档)。在我的web.config
中,我使用自定义数据库抓取工具类添加了特定的搜索索引(用于调试速度)。
public class DatabaseCrawlerExtension : Sitecore.Search.Crawlers.DatabaseCrawler
{
protected override void AddAllFields(Lucene.Net.Documents.Document document, Sitecore.Data.Items.Item item, bool versionSpecific)
{
base.AddAllFields(document, item, versionSpecific);
string fieldName;
if (/* item is of template A */)
{
var targetItems = /* get items based on a property */;
foreach (var additionalIndexItem in targetItems)
{
foreach (var fieldKey in additionalIndexItem.Fields
.Select(f => f.Key)
.Where(fk => !fk.StartsWith("_")))
{
document.Add(base.CreateValueField(fieldKey, additionalIndexItem[fieldKey]));
}
}
}
}
}
我已经调试了这段代码,并且可以看到它遇到了调用document.Add
的行,并添加了正确的数据。我尝试过不同的方法是先调用base
方法,然后尝试使用方法AddSpecialFields
代替AddAllFields
。这没有在索引中产生任何额外的数据。
要调试/查看索引,我一直在重建索引(在Sitecore中)并查看最终结果,以及使用名为Luke的工具直接查看生成的索引文件。
答案 0 :(得分:1)
这只是猜测,但您可以尝试自己创建新的base.CreateValueField()
并将其添加到文档中,而不是使用Lucene.Net.Documents.Field
。如果要使用Luke查看索引中的值,请确保在字段上将Store
设置为Field.Store.YES
,否则,该值将被编入索引,但不会存储在索引中。
答案 1 :(得分:1)
CreateValueField
是一种便捷方法,可在文档中创建索引和未存储的字段(每sitecore documentation)。 。我怀疑这是你遇到的问题。当你从索引中获取时,Luke不会显示仅索引字段,正如人们所期望的那样。
这听起来像是正确的行为,如上所述。您希望在项目B中搜索值,并返回项目A中的值,因此不需要从搜索中返回项目B中的值。尝试测试对项目B中的值的搜索是否有效,而不是仅查看存储的字段。您也可以尝试按"Reconstruct & Edit"
,这可能会构建包含未存储字段值的文档。
另一个可能的问题是您尝试在项目B中包含的数据类型。CreateValueField
尝试索引值,例如数字或日期。这些处理方式不同,我真的不知道它如何用文本值表现。如果您尝试包含文字值,则应使用CreateTextField
代替。
答案 2 :(得分:0)
以下是我的自定义媒体抓取工具的代码。它适用于我,并为 lucene 索引添加自定义值。它不会执行base.AddAllFields
,但这不应该是您的代码无效的原因。
public class MyMediaCrawler : Sitecore.Search.Crawlers.DatabaseCrawler
{
protected override void AddAllFields(Document document, Item item, bool versionSpecific)
{
MediaItem mediaItem = item;
document.Add(CreateField(Sitecore.Search.BuiltinFields.Content, item.DisplayName, true, 1f));
document.Add(CreateField("anc", String.Join(" ", item.Axes.GetAncestors().Select(a => a.ID.ToShortID())), true, 1f));
document.Add(CreateField("filename", String.IsNullOrEmpty(mediaItem.Title) ? item.DisplayName : mediaItem.Title, false, 1f));
}
}