以编程方式扩展Lucene文档以及其他字段

时间:2013-06-25 17:06:38

标签: c# .net lucene sitecore lucene.net

我正在尝试包含相关文档(特定于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的工具直接查看生成的索引文件。

3 个答案:

答案 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));
    }
}