Индексация кастомных значений в Search API

Search API - известный, удобный и полезный инструмент для сайта на Drupal.
"Из коробки" - он работает со всеми полями сущностей, будь то ноды или самописный product-entity.
Но что делать, если нужно добавить возможность индексации, а в дальнейшем фильтрации и составления фасетов по нестандартным значениям? Программировать, конечно же! )) И делается это достаточно просто.
Добавляем в индекс собственные поля сущностей с помощью Search API.
Нам понадобится всего лишь один хук - hook_entity_property_info_alter и коллбек к нему.
Вот как это выглядит:
/**
* Implements hook_entity_property_info_alter().
*/
function ИМЯ_МОДУЛЯ_entity_property_info_alter(&$info) {
$info['node']['properties']['ИМЯ_СВОЙСТВА'] = array(
// Тип данных по умолчанию
'type' => 'decimal',
// Название свойства
'label' => t('Property name'),
// Описание свойства
'description' => t('Property description'),
// Коллбек отвечающий за получение данных
'getter callback' => 'my_property_getter_callback',
);
}
/**
* Getter callback for my_property.
*
* Здесь получаем нужные нам данные и отправляем в индекс
* $item - объект сущности.
* Возвращаем данные для индексации.
*/
function my_property_getter_callback($item) {
return $item->my_property;
}
Рассмотрим подробнее.
Как это работает
Если мы посмотрим внутреннюю часть работы нашего модуля, можем увидеть следующую картину - ссылка на переменную $info, к которой мы добавляем свойства в хуке, содержит список сущностей доступных на сайте:

Которые, в свою очередь, содержат список типов сущностей (bundles) и список доступных свойств (properties):

Именно в список свойств мы добавляем новое.
Давайте, на примере, добавим новое свойство - Node ID.
Вызываем, в своем модуле, hook_entity_property_info_alter:
/**
* Implements hook_entity_property_info_alter().
*/
function module_entity_property_info_alter(&$info) {
$info['node']['properties']['my_property'] = array(
$info['node']['properties']['my_property'] = array(
'type' => 'integer',
'label' => t('My node NID'),
'description' => t('My custom field Node ID'),
'getter callback' => 'my_property_getter_callback',
);
}
- module - меняем на имя своего модуля
- type - тип данных
- label - название
- description - описание (не обязательно)
- getter callback - коллбек
- полный список свойств и типов данных есть в описании хука hook_entity_property_info
Сейчас, если открыть страницу настроек полей индекса - уже можно увидеть наше свойство:
Теперь напишем callback-функцию для нашего поля:
/**
* Getter callback for my_property.
*/
function my_property_getter_callback($item) {
return $item->nid;
}
В переменной $item содержится экземпляр текущего объекта. В нашем случае - объекта ноды.
Объект загружается полностью, поэтому если Вы переопределяли его загрузку с помощью хуков entity_load (node_load, user_load...) - все данные будут там.
При необходимости - делайте проверку перед возвратом.
После включения делаем переиндексацию, и используем результаты.
P.S. После включения свойства, если используется фасеточный поиск, среди фасетов появится и новый - со свеже-добавленным свойством. И после переиндексации его можно будет успешно применять.
Удачи!
Комментарии
Господа. Можно ли в фильтре, созданном с помощь search api, facet api, coommerce search api выбрать несколько пунктов сразу? НА пример, фильтр по бренду - выбрать несколько брендов. Если да, то как настроить. спасибо