Показ схожих информационных элементов на основе дополнительного свойства

#
Re: Показ схожих информационных элементов на основе дополнительного свойства
Хорошо, а тогда почему у меня вот это не работает?
$Informationsystem_Controller_Show = new Informationsystem_Controller_Show(Core_Entity::factory('Informationsystem', 55));
$Informationsystem_Controller_Show
   ->xsl(Core_Entity::factory('Xsl')->getByName('РодственныеВидыДревесины'))
   ->groupsMode('none')
   ->itemsForbiddenTags(array('text'))
   ->group(false)
   ->itemsProperties(true)
   ->limit(99);

$oInformationsystem_Item = Core_Entity::factory('Informationsystem_Item', 55);
$aPropertyValues = $oInformationsystem_Item->getPropertyValues();
foreach($aPropertyValues as $oPropertyValue)
   {
   echo '<br />Property ',
   htmlspecialchars($oPropertyValue->Property->name), ', value = ',
   htmlspecialchars($oPropertyValue->Property->type == 2
                           ? $oPropertyValue->file
                           : $oPropertyValue->value);

if (isset($aPropertyValues[0]) && trim($aPropertyValues[0]->value) != '') {
$Informationsystem_Controller_Show
   ->informationsystemItems()
   ->queryBuilder()
   ->leftJoin('informationsystem_item_properties', 'informationsystem_items.informationsystem_id', '=', 'informationsystem_item_properties.informationsystem_id')
   ->leftJoin('property_value_strings', 'informationsystem_items.id', '=', 'property_value_strings.entity_id',
                  array(array('AND' => array('informationsystem_item_properties.property_id', '=', Core_QueryBuilder::expression('`property_value_strings`.`property_id`')))))
   ->where('informationsystem_item_properties.property_id', '=', 262)
   ->where('property_value_strings.value', '=', $aPropertyValues[0]->value)
   ->setOr()
   ->where('informationsystem_item_properties.property_id', '=', 284)
   ->where('property_value_strings.value', '!=', $aPropertyValues[0]->value)
   ->groupBy('informationsystem_items.id')
   ->having(Core_Querybuilder::expression('COUNT(DISTINCT `informationsystem_item_properties`.`property_id`)'), '=', 2);
$Informationsystem_Controller_Show->show();
}
}
#
Re: Показ схожих информационных элементов на основе дополнительного свойства
Вот так работает, но правда для одного свойства. А мне надо для двух 262 и 284.
...
$oProperty = Core_Entity::factory('Property', 262);
$aPropertyValues = $oProperty->getValues($iItem = intval(Core_Page::instance()->object->item));

if (isset($aPropertyValues[0]) && trim($aPropertyValues[0]->value) != '') {
$Informationsystem_Controller_Show
   ->informationsystemItems()
   ->queryBuilder()
   ->leftJoin('informationsystem_item_properties', 'informationsystem_items.informationsystem_id', '=', 'informationsystem_item_properties.informationsystem_id')
   ->leftJoin('property_value_strings', 'informationsystem_items.id', '=', 'property_value_strings.entity_id',
                  array(array('AND' => array('informationsystem_item_properties.property_id', '=', Core_QueryBuilder::expression('`property_value_strings`.`property_id`')))))
   ->where('informationsystem_item_properties.property_id', '=', 262)
   ->where('property_value_strings.value', '=', $aPropertyValues[0]->value)
   ->setOr()
   ->where('informationsystem_item_properties.property_id', '=', 284)
   ->where('property_value_strings.value', '!=', $aPropertyValues[0]->value)
   ->groupBy('informationsystem_items.id')
   ->having(Core_Querybuilder::expression('COUNT(DISTINCT `informationsystem_item_properties`.`property_id`)'), '=', 2);
$Informationsystem_Controller_Show->show();
}

Здесь в условии два свойства...
Модератор
#
Re: Показ схожих информационных элементов на основе дополнительного свойства
Dmitry K.,
а зачем вы внутри цикла делаете N объединений и ограничений. Ваш блок
$Informationsystem_Controller_Show
   ->informationsystemItems()
   ->queryBuilder()
добавляет ограничения на выборку столько раз, сколько у вас значений свойств.
Модератор
#
Re: Показ схожих информационных элементов на основе дополнительного свойства
Полагаю ваш код должен быть примерно таким
$Informationsystem_Controller_Show = new Informationsystem_Controller_Show(Core_Entity::factory('Informationsystem', 55));
$Informationsystem_Controller_Show
   ->xsl(Core_Entity::factory('Xsl')->getByName('РодственныеВидыДревесины'))
   ->groupsMode('none')
   ->itemsForbiddenTags(array('text'))
   ->group(false)
   ->itemsProperties(true)
   ->limit(99);

$iItem = intval(Core_Page::instance()->object->item);

// Находимся на странице элемента
if ($iItem)
{
   $oProperty = Core_Entity::factory('Property', 262);
   $aPropertyValues262 = $oProperty->getValues($iItem);

   $oProperty = Core_Entity::factory('Property', 284);
   $aPropertyValues284 = $oProperty->getValues($iItem);

   if (isset($aPropertyValues262[0]) && trim($aPropertyValues262[0]->value) != ''
      && isset($aPropertyValues284[0]) && trim($aPropertyValues284[0]->value) != ''
   )
   {
      $Informationsystem_Controller_Show
         ->informationsystemItems()
         ->queryBuilder()
         ->leftJoin('informationsystem_item_properties', 'informationsystem_items.informationsystem_id', '=', 'informationsystem_item_properties.informationsystem_id')
         ->leftJoin('property_value_strings', 'informationsystem_items.id', '=', 'property_value_strings.entity_id',
                    array(array('AND' => array('informationsystem_item_properties.property_id', '=', Core_QueryBuilder::expression('`property_value_strings`.`property_id`')))))
         ->where('informationsystem_item_properties.property_id', '=', 262)
         ->where('property_value_strings.value', '=', $aPropertyValues262[0]->value)
         ->setOr()
         ->where('informationsystem_item_properties.property_id', '=', 284)
         ->where('property_value_strings.value', '!=', $aPropertyValues284[0]->value)
         ->groupBy('informationsystem_items.id')
         ->having(Core_Querybuilder::expression('COUNT(DISTINCT `informationsystem_item_properties`.`property_id`)'), '=', 2);

      $Informationsystem_Controller_Show->show();
   }
}
#
Re: Показ схожих информационных элементов на основе дополнительного свойства
hostcms, делаю я всё согласно Документации - Ограничения по дополнительным свойствам в контроллерах.
...или мне вот это отключить (закомментировать)?
...
$Informationsystem_Controller_Show
   //->informationsystemItems()
   //->queryBuilder()
...
Модератор
#
Re: Показ схожих информационных элементов на основе дополнительного свойства
Dmitry K.,
в инструкции не сказано поместить это все в цикл и выполнить много раз. Готовый вариант я написал вам выше.
#
Re: Показ схожих информационных элементов на основе дополнительного свойства
hostcms!
Огромное Преогромное Чисточеловеческое Спасибо!
Всё получилось!
#
Re: Показ схожих информационных элементов на основе дополнительного свойства
Добрый день, форумчане!
По предыдущему примеру я сделал выборку информационных элементов на основе двух доп. свойств:
/* 2 - Похожие по свойствам виды древесины - показ схожих инфоэлементов на основе доп. свойств */
$Informationsystem_Controller_Show = new Informationsystem_Controller_Show(Core_Entity::factory('Informationsystem', 55));
$Informationsystem_Controller_Show
   ->xsl(Core_Entity::factory('Xsl')->getByName('ПохожиеПоСвойствамВидыДревесины'))
   ->itemsProperties(true)
   ->limit(99);

$coef = 0.1;

$iItem = intval(Core_Page::instance()->object->item);
if ($iItem)
{
   $oProperty = Core_Entity::factory('Property', 264);
   $aPropertyValues264 = $oProperty->getValues($iItem);
   $oProperty = Core_Entity::factory('Property', 273);
   $aPropertyValues273 = $oProperty->getValues($iItem);
   if (isset($aPropertyValues264[0]) && trim($aPropertyValues264[0]->value) != ''
    && isset($aPropertyValues273[0]) && trim($aPropertyValues273[0]->value) != ''
         )
$delta264 = intval($aPropertyValues264[0]->value) * $coef;
$minProperty264 = $aPropertyValues264[0]->value - $delta264;
$maxProperty264 = $aPropertyValues264[0]->value + $delta264;
$delta273 = intval($aPropertyValues273[0]->value) * $coef;
$minProperty273 = $aPropertyValues273[0]->value - $delta273;
$maxProperty273 = $aPropertyValues273[0]->value + $delta273;      
   {

$Informationsystem_Controller_Show
   ->informationsystemItems()
   ->queryBuilder()
   ->leftJoin('informationsystem_item_properties', 'informationsystem_items.informationsystem_id', '=', 'informationsystem_item_properties.informationsystem_id')
   ->leftJoin('property_value_ints', 'informationsystem_items.id', '=', 'property_value_ints.entity_id',
                  array(array('AND' => array('informationsystem_item_properties.property_id', '=', Core_QueryBuilder::expression('`property_value_ints`.`property_id`')))))
   ->leftJoin('property_value_floats', 'informationsystem_items.id', '=', 'property_value_floats.entity_id',
                  array(array('AND' => array('informationsystem_item_properties.property_id', '=', Core_QueryBuilder::expression('`property_value_floats`.`property_id`')))))
   ->open()
   ->where('informationsystem_item_properties.property_id', '=', 264)
   ->where('property_value_ints.value', '>=', $minProperty264)
   ->setAnd()
   ->where('informationsystem_item_properties.property_id', '=', 264)
   ->where('property_value_ints.value', '<=', $maxProperty264)
   ->setOr()
   ->where('informationsystem_item_properties.property_id', '=', 273)
   ->where('property_value_floats.value', '>=', $minProperty273)
   ->setAnd()
   ->where('informationsystem_item_properties.property_id', '=', 273)
   ->where('property_value_floats.value', '<=', $maxProperty273)
   ->close()
   ->groupBy('informationsystem_items.id')
   ->having(Core_Querybuilder::expression('COUNT(DISTINCT `informationsystem_item_properties`.`property_id`)'), '=', 2);
      
$Informationsystem_Controller_Show->show();
}}

Всё работает хорошо, вот к примеру страница - https://www.mebelib.ru/wood-tree/cocobolo/
Но в таблицу Похожие по свойствам виды древесины попадает и сам текущий элемент, в данном случае Кокоболо.
А как сделать так, чтобы в данной программной конструкции исключить текущий элемент?
По самим доп. свойствам я этого сделать не могу.
Пытаюсь это сделать по принципу и на основе Ссылка на предыдущий и следующий товар в интернет-магазине.
Но у меня не получается. Что я делаю не так?
// Если мы находимся на странице инфоэлемента
if ($Informationsystem_Controller_Show->item) {
   $oInformationsystem_Item = Core_Entity::factory('Informationsystem_Item', $Informationsystem_Controller_Show->item);
// Текущий элемент и группа
   $cur_elem = $Informationsystem_Controller_Show->item;
   $cur_group = $oInformationsystem_Item->informationsystem_id;
   $oCore_QueryBuilder_Select = Core_QueryBuilder::select()
      ->select(''informationsystem_items.id', 'informationsystem_items.item')
      ->from('informationsystem_items')
      ->where('active', '=', 1)
      ->open()
      ->where('informationsystem_items.id', '=', $cur_elem)
      ->where('informationsystem_items.id.item', '!=', $cur_elem->item)
      ->where('informationsystem_items.id.item_id', '!=', $cur_elem->item)
      ->close();
}
Модератор
#
Re: Показ схожих информационных элементов на основе дополнительного свойства
1) Dmitry K. писал(а):
      ->where('informationsystem_items.id', '=', $cur_elem)
      ->where('informationsystem_items.id.item', '!=', $cur_elem->item)
      ->where('informationsystem_items.id.item_id', '!=', $cur_elem->item)

что-то вы совсем в фантазии пустились

2) Почему у вас расчеты $delta264 ... и так далее идут после условия, а не внутри операторных скобок {}, которые уже есть внизу? по сути то, что в операторных операторных скобках, у вас выполняется уже независимо от условия в if(), от if() зависит у вас только первая строка после if - это $delta264 = intval($aPropertyValues264[0]->value) * $coef;

3) чтобы исключить элемент, просто добавьте
->where('informationsystem_items.id', '!=', $iItem)
#
Re: Показ схожих информационных элементов на основе дополнительного свойства
Большое спасибо!
Применил 3-ий пункт и всё заработало!
С остальными Вашими замечаниями буду разбираться позже...
Авторизация