[РЕШЕНО] Facet API + XML Sitemap: как интегрировать?

Главные вкладки

Аватар пользователя Sun-fire Sun-fire 29 марта 2013 в 15:02

Собственно, столкнулся с интересной задачей:

Есть:
Фасетные отборы каталога товаров, реализованные на Facet API+Search API+Apache SOLR в бекэнде.

Нужно:
Реализовать генерацию ссылок в sitemap.xml по первому уровню фасетных отборов (одновременно активен только одно значение любого фасета).

Встречал ли кто что либо похожее (готовое, или sandbox)? Хотелось бы посмотреть подход к решению задачи. Задача не простая в первую очередь с точки зрения производительности - так как планируется использовать эту приблуду на не маленьких объемах данных:

Типов контента: около 150
Общее количество фасет (полей): около 1100
Примерно 60% фасет - поля таксономии, в среднем 10-20 терминов в словаре (есть и большие, по несколько сотен терминов в словаре).

Т. е. количество ссылок для генерации предполагается довольно большим.

Комментарии

Аватар пользователя neltharian neltharian 29 марта 2013 в 16:59

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

Аватар пользователя Sun-fire Sun-fire 29 марта 2013 в 17:21

"neltharian" wrote:
а модуль сайт мап генератор разве не берет?

Нет, к сожалению готовой интеграции нет, сайтмеп по умолчанию имеет реализации для формирования ссылок по:

  • нодам;
  • пользователям;
  • таксономии;
  • меню;
  • кастомным путям, которые пользователь вводит "от руки".
Аватар пользователя neltharian neltharian 29 марта 2013 в 17:51

хммм уникальная ситуация вы первый кто о таком спрашивает.. лоничное предположение - либо никто о таком даже и не думал и вы первый, либо решение настолько очевидно что о нем никто не пишет..

боюсь что тут именно первый случай..

а жаль вопрос кстати актуален и для меня.//

Хотя... тут же момент такой - результаты деятельности фацетов это же views тоесть вам надо копать в сторону включения views в xml sitemap тоесть например тут http://drupal.org/node/507674

Аватар пользователя Sun-fire Sun-fire 29 марта 2013 в 19:00

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

1. hook_views_pre_execute() на вьюху каталога
2. $_SERVER['REQUEST_URI'] - урла страницы. Парсим урл, чтобы реагировать только на фасетные отборы.
3. Проверяем наличие записи в XML Sitemap и при необходимости пишем новую запись. Это уже с использованием API XML Sitemap

Минусы:

1. Как то не совсем drupal-way.
2. Как минимум 1 лишний запрос к БД при вызове вьюхи (hook_views_pre_execute() на эту вьюху у меня и так используется в кастомном модуле).
3. В Sitemap попадут только те страницы, которые просматривались пользователями. Это в принципе можно решить запуском краулера по страницам.

Задачу пока закрываю, если найду более правильное решение - отпишусь сюда.

Также создал ишью по этой теме на drupal.org

Аватар пользователя frajj frajj 30 октября 2013 в 14:15

Хоть тема решена нашел еще одно решение, нагуглил https://drupal.org/node/1626468#comment-6117600
Опираясь на этот комент накатал такую функцию. Вроде работает )

<?php
function add_facets_links_to_sitemap () {
  
$links_type 'facet';
  
xmlsitemap_link_delete_multiple(array('type' => $links_type));
  
$i 999999// Not significantly, because the whole group is recreated on the new.
  
foreach (facetapi_get_searcher_info() as $searcher => $info) {
    foreach (
facetapi_get_delta_map_queue($searcher'block') as $facet_name) {
      
$adapter facetapi_adapter_load($searcher);
      
$facet facetapi_facet_load($facet_name$searcher);

      

$fild_info field_info_field($facet_name);
      
$vocab_mn = isset($fild_info['settings']['allowed_values'][0]['vocabulary']) ? $fild_info['settings']['allowed_values'][0]['vocabulary'] : '';

      if (

check_plain($vocab_mn)) {
        
$vocabulary taxonomy_vocabulary_machine_name_load($vocab_mn);
        if (isset(
$vocabulary->vid)) {

          

$tree taxonomy_get_tree($vocabulary->vid);

          

$field_bundles $fild_info['bundles']['node'];
          foreach (
$field_bundles as $content_type) {
            
$table_name 'field_data_' $facet_name;
            
$field_name $facet_name '_tid';

            if (

db_field_exists($table_name$field_name)) {

              

$tids db_select($table_name'f')
                ->
fields('f', array($field_name))
                ->
condition('f.bundle'$content_type)
                ->
groupBy('f.' $field_name)
                ->
execute()
                ->
fetchCol();

              

$href $adapter->getFacetPath($facet$tids0);

              

$expl_href explode("/"$href);

              if (isset(

$expl_href[0])) {
                if (! 
$expl_href[0]) {

                  foreach (

$expl_href as $key => $value) {
                    if (
$key != && $key == 0) {
                      
$h '/' .$expl_href[$key 1] . '/' $value;

                        

$link = array(
                          
'type'       => $links_type,
                          
'id'         => ++$i// Must beat the unique within the group.
                          
'loc'        => drupal_get_path_alias('catalog/' $content_type $h),
                          
'priority'   => '0.5',
                          
'changefreq' => '0',
                          
'language'   => 'und',
                        );
                        
xmlsitemap_link_save($link);
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
?>