Всем привет.
Сделал программное добавление данных в индекс. Данные представляют из себя список характеристик, закрепленных за нодой.
Поиск по этим характеристикам работает отлично, но не хватает вот чего:
search api сохраняет индексы в таблицу, где в столбце "item_id" указана нода.
Как видим значение "entity:node/1013:ru" прекрасно позволяет получить ноду при поиске.
Мне нужно к "entity:node/1013:ru" добавить еще номер характеристики. к примеру так "entity:node/1013:ru:412".
Так вот вопрос, можно ли как о при программном добавлении индексов, влиять на значение столбца "item_id"?
з.ы.: если кратко о задаче, которую делаю. Поиском находим товар. При переходе в товар. надо отобразить нужную характеристику, по которой нашелся товар.
Индексы вот так добавляю:
<?php
namespace Drupal\oc_product_variants\Plugin\search_api\processor;
use
Drupal\Core\Entity\EntityInterface;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Processor\ProcessorProperty;
/**
*
* @SearchApiProcessor(
* id = "product_variants_search",
* label = @Translation("Product variants search"),
* description = @Translation("Product variants search"),
* stages = {
* "add_properties" = 0,
* },
* locked = true,
* hidden = true,
* )
*/
class ProductVariantsSearch extends ProcessorPluginBase {
/**
* {@inheritdoc}
*/
public static function supportsIndex(IndexInterface $index) {
foreach ($index->getDatasources() as $datasource) {
if ($datasource->getEntityTypeId() == 'node') {
return TRUE;
}
}
return FALSE;
}
/**
* {@inheritdoc}
*/
public function getPropertyDefinitions(DatasourceInterface $datasource = NULL) {
$properties = [];
if (!
$datasource) {
$definition = [
'label' => $this->t('Product variants'),
'description' => $this->t('Product variants search'),
'type' => 'string',
'processor_id' => $this->getPluginId(),
];
$properties['product_variants_search'] = new ProcessorProperty($definition);
}
return
$properties;
}
/**
* {@inheritdoc}
*/
public function addFieldValues(ItemInterface $item) {
$entity = $item->getOriginalObject()->getValue();
if (
$entity instanceof EntityInterface && $entity->getType() == 'tovar') {
$values = [];
// Получаем все значения свойств у вариаций для ноды
$q = \Drupal::database()->select('oc_pv_parameters', 'f1');
$q->fields('f1', ['pv_id', 'value']);
$q->condition('f1.nid', $entity->id());
$res = $q->execute();
while($rec = $res->fetchAssoc()){
$pattern = '/^[EЕ]{1}\d{1,5}(-){1}\d{1,5}$/msiu';
if(preg_match($pattern, $rec['value'])){
$rec['value'] = str_replace('//', '', $rec['value']);
$rec['value'] = str_replace(['E','Е'], '', $rec['value']);
$rec['value'] = str_replace('-', '', $rec['value']);
}
// Исключаем дубликаты записей
$values[$rec['pv_id']][$rec['value']] = $rec['value'];
}
$fields = $this->getFieldsHelper()
->filterForPropertyPath($item->getFields(), NULL, 'product_variants_search');
foreach ($fields as $field) {
foreach($values as $pv_id=>$value){
$field->addValue(implode(' ', $value));
}
}
}
}
}?>
Комментарии
Зачем менять то что индексируете? Вы индексируете товар. Добавьте просто поле-характеристика
Если надо отобразить характеристики по которым нашёлся товар при переходе в него, я бы просто js разрулил - добавив бы к ссылкам соответствующие параметры а далее в самом товаре их обработал бы. Думаю не надо здесь лезть в search api
ссылки у меня формируются в поиске примерно такие "www.site.ru/product-1". Я хочу добавить к ссылке № параметра, так - "www.site.ru/product-1?id=100". Для этого мне и нужно при поиске получать не только ноду, но и номер параметра
ну вот и добавляйте к ссылкам на продукты www.site.ru/product-1 параметры из поискового запроса
так у меня нет этого параметра). мне его для начала нужно связать с search api, что бы search api мне его выдавал при поиске. про это вопрос и был.
так индексируйте эту характеристику - добавляйте поле, далее поиск/фасет - и будет вам эта характеристика, всё это можно программно или вьюсом
я характеристику индексирую. по характеристикам поиск работает, но я не могу получить номер характеристики. есть только номер ноды
характеристика - это поле в товаре?
нет, к полям отношение не имеет. если было бы поле, то я через интерфейс search api его добавил и проблем не было).
ну хорошо. Ты создал своё поле search api программно и его добавил в индекс, в результате получил в таблице строки вида:
сущность/значение_характеристики
это нормально. Потому что когда ты будешь искать по этой характеристики у тебя в URL будет что-то вроде:
search?keywords=значение
Так вот и подставляй js эти параметры ?keywords=значение к URl товара на странице выдачи, а уже когда перешёл на страницу самого товара - обрабатывай их, хоть в контроллере
как-то костыльно это выглядит. уверен, что можно без js обойтись, должна быть возможность связать номер характеристики с search api. пока не могу понять как. если сам разберусь, то выложу тут решение или может, кто подскажет еще)
А где костыль?
Как раз то что вы делаете - это костыль.
Почему все думают что js - это костыль?
ну вот, начинаем костылями мериться)). про костыль вам не в обиду было сказано, не принимайте на свой счет.
js за костыль не считаю, но в конкретно в этом случае это не самое лучшее решение. search api мощный модуль, работаю с ним буквально пару недель. уверен, что просто не до конца понимаю его. по этому и задал тут вопрос
Да я не принял. ))
Ну уж если вы говорите костыльно, то тогда аргументируйте: дайте кейс где это вылезет в костыль?
Как раз в этой задаче - это самое разумное решение.
Да и СЕОшники, думаю, вам за него спасибо скажут )
я вот не пойму, а что даст вам связь номера характеристики с search api? Вам же всё равно надо будет в товар передать её? А как передавать то собираетесь?
передавать через get параметр
контроллер сущности альтерить?