2013-06-25 4 views
2

Я пытаюсь включить связанный документ (Sitecore - в частности, документ Lucene - это Item), так что, когда индекс Lucene создает документ для элемента типа A, он будет также включают все свойства из другого объекта B.Запрограммировать документ Lucene с дополнительными полями

Конечным результатом является то, что, когда пользователь ищет данные, найденные на элементе 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.

ответ

1

Это только предположение, но вместо того, чтобы использовать base.CreateValueField(), вы можете попробовать создать новый Lucene.Net.Documents.Field и добавить его в документ. Если вы хотите увидеть значение в индексе с помощью Luke, обязательно установите Store в Field.Store.YES в поле, иначе значение будет проиндексировано, но не будет сохранено в индексе.

+0

Спасибо за точку Луки и 'Field.Store' - инструмент, однако, довольно сложны в использовании, так что я, как правило, использовать его только для проверки конечного результата – Simeon

+0

я попробую с помощью конструктора на' Field' – Simeon

1

CreateValueField это удобный метод, который создает несохраненные поле индексируется и в документе (за sitecore documentation). , Я подозреваю, что это проблема, с которой вы сталкиваетесь. Люк не будет отображать только индексные поля, если они будут получены из индекса, как и следовало ожидать.

Это похоже на правильное поведение для вашего использования, как описано. Вы хотите найти значения в Item B и вернуть значения в Item A, поэтому значения в Item B не нужно возвращать из поиска. Попробуйте проверить, является ли поиск по значению из пункта B функциональным, а не просто просмотр сохраненных полей. Вы также можете попробовать нажать "Reconstruct & Edit", что может привести к созданию документа, содержащего неактивные значения полей.

Другая возможная проблема заключается в типе данных, которые вы пытаетесь включить из Item B. CreateValueField пытается индексировать значение, например число или дату. Они обрабатываются по-разному, и я не знаю, как он будет вести себя с текстовым значением. Если вы пытаетесь включить текстовые значения, вместо этого вы должны использовать CreateTextField.

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)); 
    } 
} 
Смежные вопросы