SharePoint 2013 Enterprise Search. Часть 2. Создание обработчика контента
Часть 1. Логическая архитектура поиска в SharePoint 2013
Часть 2. Создание дополнительного обработчика контента для поиска в SharePoint 2013
Поиск в SharePoint 2013 допускает наличие дополнительного обработчика контента при его индексировании. В этом посте я опишу процесс создания такого обработчика.
Дополнительный обработчик должен быть реализован в виде WCF-сервиса, который будет принимать указанные в его настройках входные свойства и возвращать выходные свойства.
Сначала небольшое введение про сами свойства. Они бывают двух видов: Свойства для обхода (Crawled Property) и Управляемые свойства (Managed Property).
Свойства для обхода (Crawled Property)
Свойства для обхода содержат информацию о содержимом и извлекаются при обходе содержимого. Набор этих свойств зависит от типа содержимого контента и может настраиваться. Значения этих свойств используются при наполнении поискового индекса и, соответственно, используются при поиске.
Свойства для обхода автоматически добавляются при создании новых столбцов в списках/библиотеках и их имена имеют следующий формат: **ows_**InternalName (InternalName - внутреннее имя поля). Свойство будет создано при обходе содержимого.
Свойства для обхода могут быть ассоциированы с управляемыми свойствами.
Получение списка свойств для обхода
Чтобы просмотреть список всех доступных свойств для обхода на странице администрирования поиска в разделе Queries and Results надо перейти по ссылке Search Schema:
Используя PowerShell, можно получить список с помощью командлета Get-SPEnterpriseSearchMetadataCrawledProperty примерно так:
$ssa = Get-SPEnterpriseSearchServiceApplication
Get-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $ssa
Управляемые свойства (Managed Property)
Управляемые свойства используются для уточнения результатов поиска, а также для управления моделью ранжирования содержимого.
Получение списка управляемых свойств
Просмотреть управляемые свойства можно там же где и свойства для обхода (см. выше).
Для получения списка управляемых свойств с помощью PowerShell, необходимо использовать командлет Get-SPEnterpriseSearchMetadataManagedProperty:
$ssa = Get-SPEnterpriseSearchServiceApplication
Get-SPEnterpriseSearchMetadataManagedProperty -SearchApplication $ssa
При создании дополнительного обработчика содержимого использоваться будут именно управляемые свойства (Managed Property).
Обработчик контента
Теперь перейдем к созданию самого обработчика. Для этого в Visual Studio создадим новый WCF-сервис аналогично инструкции на MSDN:
Метод ProcessItem(Item item)
В обработчик передается один аргумент типа Microsoft.Office.Server.Search.ContentProcessingEnrichment.Item. Вот его диаграмма:
Содержимое объекта item может выглядеть примерно вот так:
Чтение свойств индексируемого файла
Байты, представляющие индексируемое содержимое можно получить через свойство item.RawData. Остальные свойства, например имя файла ("FileName"), можно получить, используя следующий код:
// Имя свойства
var fileNamePropName = "FileName";
// Само свойство
var fileNameProp = item.ItemProperties.FirstOrDefault(p => p.Name == fileNamePropName);
// Значение свойства
var fileName = fileNameProp == null
? string.Empty // По умолчанию string.Empty
: (string) fileNameProp.ObjectValue;
Сначала получаем экземпляр AbstractProperty и затем, если оно не равно null, получаем его значение. При это надо помнить, что вместо одного значения, можно получить массив, который будет содержать различные варианты этого значения. Например, свойство "Author" может быть представлено в виде массива, если значение ссылается на системную учетную запись (SHAREPOINT\System). В моем случае это были значения: "System account" и "Vitaly Zhukov".
Задание значений для выходных свойств
Класс AbstractProperty является абстрактным, поэтому для задания свойств не подходит. Здесь нам поможет класс Microsoft.Office.Server.Search.ContentProcessingEnrichment.PropertyTypes.Property<T>, унаследованное от AbstractProperty:
Для примера предположим, что у нас есть управляемые свойства "ImageUrl" (ссылка на изображение товара) и "Category" (категория товара), которые будут заполняться исходя из содержимого индексированного файла. Оба свойства имеют текстовый тип. Задавать их значения можно примерно так:
// Ссылка на изображение
Property<string> imageUrl = new Property<string> {
Name = "ImageUrl",
Value = "http://site/images/image.png"
};
// Категория
Property<string> category = new Property<string> {
Name = "Category",
Value = "Телевизор"
};
// Добавляем свойства
processedItemHolder.ItemProperties.Add(imageUrl);
processedItemHolder.ItemProperties.Add(category);
Теперь эти свойства можно использовать для:
- уточнения поиска (для этого подходят только управляемые свойства);
- поиска, если они ассоциированы со свойствами для обхода;
- вывода их значения в результатах поиска;
Еще раз про свойства обработчика
В обработчике могут быть использованы только управляемые свойства (Managed Property) для параметров InputProperties и OutputProperties. Входные свойства (InputProperties), будут переданы только те, которые указаны. Если их нет, то ничего передано не будет (никаких свойств с null-значениями). Выходные свойства (OutputProperties) можно передавать какие угодно, но в индекс попадут только те, которые явно указаны в параметрах обработчика. Между собой входные и выходные свойства никак не связаны, входные свойства можно вообще не передавать, а выходные формировать на основе файла, подлежащего индексации.
Регистрация обработчика
Созданный сервис можно зарегистрировать с помощью следующего PowerShell-скрипта (из MSDN):
# Получаем экземпляр службы поиска
$ssa = Get-SPEnterpriseSearchServiceApplication
# Получаем конфигурацию наполнения индекса
$config = New-SPEnterpriseSearchContentEnrichmentConfiguration
# Добавляем новый обработчик
$config.Endpoint = http:http://sp2013:54927/ContentProcessing.svc
# Указываем входные параметры. Их может не быть вовсе
$config.InputProperties = "Author", "Filename"
# Указываем выходные параметры
$config.OutputProperties = "Author"
# Указываем, передавать ли в обработчик индексируемый файл
$config.SendRawData = $True
# Максимальный размер передаваемого файла
$config.MaxRawDataSize = 8192
# Сохраняем конфигурацию в службе поиска
Set-SPEnterpriseSearchContentEnrichmentConfiguration –SearchApplication $ssa –ContentEnrichmentConfiguration $config
При задании конфигурации все краулеры должны быть остановлены, иначе вылетит исключение, примерно вот такое:
Set-SPEnterpriseSearchContentEnrichmentConfiguration : Cannot bind parameter 'ContentEnrichmentConfiguration'.
Cannot convert the "$ssa = Get-SPEnterpriseSearchServiceApplication" value of type "System.String" to
type "Microsoft.Office.Server.Search.Cmdlet.PipeBind.ContentEnrichmentConfigurationPipeBind".
At line:1 char:1
+ Set-SPEnterpriseSearchContentEnrichmentConfiguration -SearchApplication $ssa
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-SPEnterpris...ntConfiguration], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.Office.Server.Search.Cmdlet.SetContentEnrichmentConfiguration
Говорится в нем о несоответствии типа, хотя дело в другом.
Важным моментом является то, что дополнительный обработчик может быть только один. С одной стороны это хорошо - бардака в такой конфигурации просто быть не может, но и гибкость страдает.
Вывод управляемых свойств в результатах поиска
Для вывода управляемых свойств в результатах поиска, они должны быть явно указаны. В случае с REST API нового поиска, их можно указать в параметрах запроса через QueryString. Ссылка в этом случае будет иметь следующий вид:
http://sharepointserver/_api/search/query/querytext='keyword'&selectproperties='ManagedPropertyName':
Подробнее про параметры запроса здесь.