Поиск SharePoint 2013. Кастомная модель ранжирования

Небольшой пример использования кастомной модели ранжирования при создание решений, основанных на поиске SharePoint 2013.

В этом примере я покажу как создать поиск сотрудников, информация о которых хранится в списке. При этом будет создана простая кастомная модель ранжирования, обеспечивающая необходимое ранжирование.

Список

Список будет предельно простым, содержащим следующие поля:

  • FullName (Title) - полное имя сотрудника. Конкатенация значений полей Surname, Name;
  • Surname - фамилия сотрудника;
  • Name - имя сотрудника;
  • Position - должность;
  • Grade - уровень грейда (целое число от 0 до 5);

Тестовые данные:

Тестовые данные

Тестовые данные

Требования к ранжированию

Модель ранжирования должна следовать следующим приоритетам при расчете ранга:

  • выводить только сотрудников и никакой больше информации;
  • вхождения, найденные в поле Surname являются наиболее важными;
  • вхождения, найденные в поле Position являются вторыми по важности;
  • выводить выше остальных результатов, равных по количеству вхождений, сотрудников с наиболее высоким грейдом.

При поиске "bell" должны быть выведены сотрудники по фамилии Bell в слдующем порядке:

  • John Bell (grade=4)
  • Robert Bell (grade=4)
  • Jessica Bell (grade=1)
  • Larry Bell (grade=0)

Контрольная группа

Перед тем как приступить посмотрим, как работает стандартная модель ранжирования:

Результаты поиска при использовании стандартной модели ранжирования

Результаты поиска при использовании стандартной модели ранжирования

В результатах поиска кладовщик оказался выше своего руководства, что неприемлемо. Конечно со временем, когда пользователи будут переходить по ссылкам в результатах поиска (игнорируя кладовщика), модель ранжирования "обучится" и опустит вниз результаты поиска, переходы по которым не осуществляются. Но бизнес не ждет.

Модель ранжирования

Для реализации нам понадобится кастомная модель ранжирования. В нашем случае нет необходимости в нейронных сетях, будет достаточно простой линейной модели. Болванка для будущей модели:

<RankingModel2Stage name="Employee OneStage Linear Model" description="" id="{GUID}" xmlns="urn:Microsoft.Search.Ranking.Model.2NN">
<RankingModel2NN id="{GUID}" precalcEnabled="1">
  <HiddenNodes count="1">
    <Thresholds>
      <Threshold>0.000405176389917475</Threshold>
    </Thresholds>
    <Layer2Weights>
      <Weight>1</Weight>
    </Layer2Weights>
  </HiddenNodes>
  <RankingFeatures>
    <!-- Features -->
  </RankingFeatures>
</RankingModel2NN>  
</RankingModel2Stage>

Вес и пороговое значение для скрытого нейрона в нашем случае значения не имеют. Главное, что вес не был нулевым, иначе ранг будет нулевой и пороговое значение нейрона должно быть достаточно малым.

Стандартную фичу поиска вхождений в тексте (BM25Main) настраиваем на поиск только в полях Surname, Name, Position. Остальные поля нас не интересуют. Веса расставляем в соответствии с требованиями:

<RankingModel2Stage name="Employee Search Model" description="" id="{GUID}" xmlns="urn:Microsoft.Search.Ranking.Model.2NN">
<RankingModel2NN id="{GUID}" precalcEnabled="1">
  <HiddenNodes count="1">
    <Thresholds>
      <Threshold>0.000405176389917475</Threshold>
    </Thresholds>
    <Layer2Weights>
      <Weight>1</Weight>
    </Layer2Weights>
  </HiddenNodes>
  <RankingFeatures>
    <!-- Features -->
  </RankingFeatures>
</RankingModel2NN>  
</RankingModel2Stage>

Требования выводить сначала сотрудников с более высоким грейдом нам поможет решить фича BucketedStatic. С помощью этой фичи можно изменять значения ранга в зависимости от значения свойства (что-то вроде оператора switch в C#):

<BucketedStatic name="EmployeeGrade" default="0" propertyName="EmployeeGrade">
  <Bucket name="0" value="0"><HiddenNodesAdds><Add>0</Add></HiddenNodesAdds></Bucket>
  <Bucket name="1" value="1"><HiddenNodesAdds><Add>1</Add></HiddenNodesAdds></Bucket>
  <Bucket name="2" value="2"><HiddenNodesAdds><Add>2</Add></HiddenNodesAdds></Bucket>
  <Bucket name="3" value="3"><HiddenNodesAdds><Add>3</Add></HiddenNodesAdds></Bucket>
  <Bucket name="4" value="4"><HiddenNodesAdds><Add>4</Add></HiddenNodesAdds></Bucket>
  <Bucket name="5" value="5"><HiddenNodesAdds><Add>5</Add></HiddenNodesAdds></Bucket>
</BucketedStatic>

Новая модель готова. Для начала регистрируем её с помощью PowerShell скрипта из MSDN:

$myRankingModel = Get-Content .\myrm.xml 
$myRankingModel = [String]$myRankingModel
$ssa = Get-SPEnterpriseSearchServiceApplication
$owner = Get-SPenterpriseSearchOwner -Level ssa
$newrm = New-SPEnterpriseSearchRankingModel -SearchApplication $ssa -Owner $owner -RankingModelXML $myRankingModel</pre>

Модель в SharePoint зарегистрирована, можно приступать к настройке интерфейса.

Интерфейс пользователя

Поиск сотрудников будет реализован на отдельной странице. Добавляем на неё веб-части Search Box и Search Results. В свойствах веб-части Search Results открываем диалог для настройки запроса:

Для выбора модели ранжирования переходим на вкладку Sorting. Указываем поле сортировки (Rank) и модель ранжирования (Employee OneStage Linear Model):

Чтобы в результатах были только сотрудники можно добавить фильтр к запросу по типу содержимого. Для этого на вкладке Basics к тексту запроса (Query text) дописываем соответствующий фильтр:

ContentType=CustomEmployee

Все готово. Сохраняем изменения и проверяем результат.

Результат

При запросе "bell":

При запросе "john*":

Все работает отлично. Можно изменить веса полей Surname и Name, чтобы совпадение найденное в фамилии было более важным, чем совпадение в имени. В этом случае Ивановы будут выше Иванов в результатах поиска.

Простое решение, основанное на поиске SharePoint 2013, реализация которого укладывается в 2 часа. И никакого кодинга.

Напоследок модель ранжирования целиком:

<RankingModel2Stage name="Employee OneStage Linear Model"
        description=""
        id="825f23c2-f06f-49a0-8b9f-2d2d754bf459"
        xmlns="urn:Microsoft.Search.Ranking.Model.2NN">
  <RankingModel2NN id="f7c4bce6-7f55-4b79-97e8-cf79a795a12b"
        precalcEnabled="0">
    <HiddenNodes count="1">
      <Thresholds>
        <Threshold>0.000405176389917475</Threshold>
      </Thresholds>
      <Layer2Weights>
        <Weight>1</Weight>
      </Layer2Weights>
    </HiddenNodes>
    <RankingFeatures>
      <!-- Поиск в содержимом -->
      <BM25Main name="ContentRank" k1="1">
        <Layer1Weights>
          <Weight>0.267001870579081</Weight>
        </Layer1Weights>
        <!-- Свойства и их веса -->
        <Properties>
          <Property name="EmployeeSurname" w="10" b="0.5" propertyName="EmployeeSurname" />
          <Property name="EmployeeName" w="10" b="0.5" propertyName="EmployeeName" />
          <Property name="EmployeePosition" w="5" b="0.5" propertyName="EmployeePosition" />
        </Properties>
      </BM25Main>
      <!-- Ранг на основе значения поля -->
      <BucketedStatic name="EmployeeGrade" default="0" propertyName="EmployeeGrade">
        <Bucket name="0" value="0"><HiddenNodesAdds><Add>0</Add></HiddenNodesAdds></Bucket>
        <Bucket name="1" value="1"><HiddenNodesAdds><Add>1</Add></HiddenNodesAdds></Bucket>
        <Bucket name="2" value="2"><HiddenNodesAdds><Add>2</Add></HiddenNodesAdds></Bucket>
        <Bucket name="3" value="3"><HiddenNodesAdds><Add>3</Add></HiddenNodesAdds></Bucket>
        <Bucket name="4" value="4"><HiddenNodesAdds><Add>4</Add></HiddenNodesAdds></Bucket>
        <Bucket name="5" value="5"><HiddenNodesAdds><Add>5</Add></HiddenNodesAdds></Bucket>
      </BucketedStatic>
    </RankingFeatures>
  </RankingModel2NN>
</RankingModel2Stage>

P.S.

Кому интересен поиск в SharePoint 2013 и его новые возможности - регистрируйтесь на трансляцию октябрьской встречи RuSUG 17 октября. Будет интересно.

Виталий Жуков

Виталий Жуков

SharePoint архитектор, разработчик, тренер, Microsoft MVP (Office Development). Более 15 лет опыта работы с SharePoint, Dynamics CRM, Office 365, и другими продуктами и сервисами Microsoft.

Смотрите также

Поиск на базе SharePoint 2013. Продажа

Поиск на базе SharePoint 2013. Продажа

Поиск SharePoint 2013. Ранжирование на основе нейронных сетей

Поиск SharePoint 2013. Ранжирование на основе нейронных сетей

Поиск SharePoint 2013. Профилирование краулера

Поиск SharePoint 2013. Профилирование краулера

Поиск для сайта на базе SharePoint 2013. Часть 1: robots.txt, sitemap.xml и другие особенности

Поиск для сайта на базе SharePoint 2013. Часть 1: robots.txt, sitemap.xml и другие особенности

Поиск для сайта на базе SharePoint 2013. Часть 2. Адаптация сайта

Поиск для сайта на базе SharePoint 2013. Часть 2. Адаптация сайта