Forums / Extensions / eZFind how to force update of object relationslist

eZFind how to force update of object relationslist

Author Message

Lars Eirik R

Wednesday 10 November 2010 5:56:36 am

My article has a related content which has changed its name. This name needs to be reflected in the lucene index as well. Is there an easy way to do this?

It seems to not help just to republish the article..

Patrick Kaiser

Wednesday 10 November 2010 8:39:26 am

I wrote a simple script to do that. There may be smarter ways to archive this, but the script works fine for me. Just adjust the settings under configuration..

<?php
/**
 * Script to update Objects to respect changes in related Objects
 * 
 * Drop this file in your ez doc-root and adjust the settings
 * then run: ezdocroot # php update_related_object_attributes.php
 * 
 * @author Patrick Kaiser <pk@okapi.de>
 * @version 1.0
 */


// Configuration

// Parent node_id where to fetch the objects from
$fetch_parent_node = 80;

// how many objects should be fetched, use offset?
$fetch_limit = 1000;
$fetch_offset = 0;

// define the content_classes to fetch
$fetch_include_content_classes = array( 
    'program' 
);

// set this to the user_id you want (must have permissions to read and edit the objects
$modify_user_id = 14;

// define the attribute_identifiers which hold object relations you want to update
$related_attributes = array( 
    'related_languages', 'related_regions_countries', 'related_program_lenght', 'related_pre_experience' 
);

// END Configuration



// ez bootstrap
require_once 'autoload.php';

// ez script init
$script_params = array( 
    'description' => "Script to update Objects to respect changes in related Objects", 'use-session' => false, 
    'use-modules' => true, 'use-extensions' => true, 'user' => true 
);
$script = eZScript::instance( $script_params );
$script->startup();
$script->initialize();

// init cli instance
$cli = eZCLI::instance();
$cli->setUseStyles( true );
$cli->output( $cli->stylize( 'cyan', "Starting to update object relations \n\n" ), false );

// set ez user
$user = eZUser::fetch( $modify_user_id );
eZUser::setCurrentlyLoggedInUser( $user, $modify_user_id );

// fetch params
$fetch_params = array( 
    'Limit' => $fetch_limit, 'ClassFilterType' => 'include', 'ClassFilterArray' => $fetch_include_content_classes, 
    'Offset' => $fetch_offset 
);
$objects_to_update = eZContentObjectTreeNode::subTreeByNodeID( $fetch_params, $fetch_parent_node );


$search_engine = new eZSolr();
$update_count = count( $objects_to_update );
foreach( $objects_to_update as $index => $object_to_update )
{
    $cli->output( $cli->stylize( 'red', "Updating Object {$index} of {$update_count}\n" ), false );
    
    // get the actual object
    $object = $object_to_update->attribute( 'object' );
    
    // print debug information
    $debug = "-- ID: {$object->ID}\n";
    $debug .= "-- Name: {$object->Name}\n";
    $cli->output( $debug, false );
    
    // get the data_map
    $data_map = $object_to_update->attribute( 'data_map' );
    
    // loop through the related_objects attributes
    foreach( $related_attributes as $rel_attr_id )
    {
        if( !isset( $data_map[ $rel_attr_id ] ))
            continue;
            
        $cli->output( $cli->stylize( 'cyan', "Updating relations for attribute {$rel_attr_id}\n" ), false );
        
        // get the attribute
        $rel_attr = $data_map[ $rel_attr_id ];
        $rel_attr_content = $rel_attr->Content();
        
        // store the object ids
        $rel_attr_obj_ids = array();
        foreach( $rel_attr_content[ 'relation_list' ] as $relObject )
        {
            $rel_attr_obj_ids[] = $relObject[ 'contentobject_id' ];
        }
        
        $debug = "-- FOUND " . count( $rel_attr_obj_ids ) . " Relations to update...\n";
        $cli->output( $debug, false );
        
        // init new objectrelation attribute
        $newRelationList = new eZObjectRelationListType();
        
        // prepare the value to use with toString ("123-34657-58756")
        $newRelationListString = implode( "-", $rel_attr_obj_ids );
        
        $debug = "-- newRelationListString: {$newRelationListString}\n";
        $cli->output( $debug, false );
        
        // use toString method to set the value and store the attribute
        $newRelationList->fromString( $rel_attr, $newRelationListString );
        $rel_attr->store();
    }
    
    // save the object
    $object->store();
    
    $debug = "-- New relations stored, updating Solr...\n";
    $cli->output( $debug, false );
    
    // trigger reindexing the document with solr
    $search_engine->addObject( $object, true );
    
    $debug = "-- Done ...\n\n";
    $cli->output( $debug, false );
}


$cli->output( "\n", false );
$script->shutdown();
?>


Best regards,

Patrick

Lars Eirik R

Thursday 11 November 2010 5:04:20 am

Thanks for the code:)

I have tried to run it and the script executes nicely, however the object relations do not update to reflect the name of the recently changed object.

I am not sure how to solve that.

i have an object with the name "People". All articles which are associated with "Peopl" now needs to be changed with the tag "People and places". Stored in the lucene document originally is "People", so when i do a search all articles initially will match and present themselfes as i want to.

However if People and Places is the new name, then this has to be reflected in the lucene document as well. I was hoping that $search_enging->addObject() would do this, but i am not able to get it to work:(

Thanks for helping and feel free to update with your ideas:)

Patrick Kaiser

Thursday 11 November 2010 6:58:36 am

Hm, strange. Which types of relations do you use?

My script only works for the object_relations datatype.

The "problem" with this datatype is, that it not only stores the object_ids of the related objects, but also their versions. The script actually does nothing else then to re-relate the existing related_objects to the newest version.

And you are right, reindexing to solr actually happens here:

$search_engine->addObject($object,true);

Mayby you could try to run updatesearchindexsolr, just to make sure you have a fresh and clean index.

php extension/ezfind/bin/php/updatesearchindexsolr.php -s YOUR_SITEACCESS -d all -v --php-exec=php --clean-all


Best regards,

Patrick

Lars Eirik R

Sunday 28 November 2010 4:17:15 pm

Hi Patrick.

After looking at the code and reinvestigating my needs i was able to solve this..

It turned out that i actually need to find all reverse_related_objects for each of my requested_objects, not the datamap. By iterating over the reversel_related objects i was able to get their datamap and consequently updated their related_object list with the updated keywords:)

Modifying your code i was able to fix this issue of mine.

So now i probably need to just have this routine run after each fo my topics have been updated. This will make it possible to run the workflow only after an object has been updated.

Simon Boyer

Friday 12 August 2011 1:12:49 am

Hi,

There is a workflow to execute after publish a related object, written from your work :

This workflow updates and re-indexes reverse related objects of modified node (ezfind+solr)

 <?php

require_once( 'kernel/common/template.php' );

class orUpdateType  extends eZWorkflowEventType
{
    const WORKFLOW_TYPE_STRING = "orupdate";
    const HTML_CONTENT_TYPE = 'text/html';

    var $site_ini;

    function __construct()
    {
        $this->eZWorkflowEventType( self::WORKFLOW_TYPE_STRING, ezpI18n::tr( 'workflow/event', 'Objects Relation Update' ) );
        $this->setTriggerTypes( array( 'content' => array( 'publish' => array( 'after') ) ) );
        $this->site_ini = eZIni::instance('site.ini');
    }


    function execute( $process, $event )
    {

        $parameters = $process->attribute( 'parameter_list' );
        $relateds_objects = eZContentFunctionCollection::fetchReverseRelatedObjects( $parameters['object_id']  , '', true, true);

        foreach($relateds_objects['result'] as $attributeId => $object_list) {
            $attribut = eZContentFunctionCollection::fetchClassAttribute($attributeId);
            $attribut = $attribut['result'];
    
            foreach($object_list as $objet) {
                
                $data_map = $objet->attribute( 'data_map' );
            
                // get the attribute
                $rel_attr = $data_map[ $attribut->Identifier ];
                $rel_attr_content = $rel_attr->Content();
                
                // store the object ids
                $rel_attr_obj_ids = array();
                foreach( $rel_attr_content[ 'relation_list' ] as $relObject )
                {
                    $rel_attr_obj_ids[] = $relObject[ 'contentobject_id' ];
                }
            
                // init new objectrelation attribute
                $newRelationList = new eZObjectRelationListType();
             
                // prepare the value to use with toString ("123-34657-58756"blunk.gif Emoticon
                $newRelationListString = implode( "-", $rel_attr_obj_ids );
             
                // use toString method to set the value and store the attribute
                $newRelationList->fromString( $rel_attr, $newRelationListString );
                $rel_attr->store();
                
                eZContentOperationCollection::registerSearchObject( $objet->attribute('id'), false );
                
            }
        }

        return eZWorkflowType::STATUS_ACCEPTED;
    }

}

eZWorkflowEventType::registerEventType( orUpdateType::WORKFLOW_TYPE_STRING, 'orUpdateType' );

?>

--
Developer at Open Wide

eZ debug

Timing: Jan 17 2025 21:00:47
Script start
Timing: Jan 17 2025 21:00:47
Module start 'content'
Timing: Jan 17 2025 21:00:47
Module end 'content'
Timing: Jan 17 2025 21:00:47
Script end

Main resources:

Total runtime0.7407 sec
Peak memory usage4,096.0000 KB
Database Queries205

Timing points:

CheckpointStart (sec)Duration (sec)Memory at start (KB)Memory used (KB)
Script start 0.00000.0044 597.6250180.8203
Module start 'content' 0.00440.6392 778.4453699.7031
Module end 'content' 0.64360.0971 1,478.1484349.2891
Script end 0.7406  1,827.4375 

Time accumulators:

 Accumulator Duration (sec) Duration (%) Count Average (sec)
Ini load
Load cache0.00360.4874210.0002
Check MTime0.00130.1757210.0001
Mysql Total
Database connection0.00050.070510.0005
Mysqli_queries0.658288.86192050.0032
Looping result0.00170.22792030.0000
Template Total0.721697.420.3608
Template load0.00170.225320.0008
Template processing0.719997.185320.3599
Template load and register function0.00010.018110.0001
states
state_id_array0.00050.073610.0005
state_identifier_array0.00080.102220.0004
Override
Cache load0.00150.1994400.0000
Sytem overhead
Fetch class attribute can translate value0.00120.159940.0003
Fetch class attribute name0.00130.176190.0001
XML
Image XML parsing0.00570.763740.0014
class_abstraction
Instantiating content class attribute0.00000.0033120.0000
General
dbfile0.00650.8788390.0002
String conversion0.00000.000530.0000
Note: percentages do not add up to 100% because some accumulators overlap

CSS/JS files loaded with "ezjscPacker" during request:

CacheTypePacklevelSourceFiles
CSS0extension/community/design/community/stylesheets/ext/jquery.autocomplete.css
extension/community_design/design/suncana/stylesheets/scrollbars.css
extension/community_design/design/suncana/stylesheets/tabs.css
extension/community_design/design/suncana/stylesheets/roadmap.css
extension/community_design/design/suncana/stylesheets/content.css
extension/community_design/design/suncana/stylesheets/star-rating.css
extension/community_design/design/suncana/stylesheets/syntax_and_custom_tags.css
extension/community_design/design/suncana/stylesheets/buttons.css
extension/community_design/design/suncana/stylesheets/tweetbox.css
extension/community_design/design/suncana/stylesheets/jquery.fancybox-1.3.4.css
extension/bcsmoothgallery/design/standard/stylesheets/magnific-popup.css
extension/sevenx/design/simple/stylesheets/star_rating.css
extension/sevenx/design/simple/stylesheets/libs/fontawesome/css/all.min.css
extension/sevenx/design/simple/stylesheets/main.v02.css
extension/sevenx/design/simple/stylesheets/main.v02.res.css
JS0extension/ezjscore/design/standard/lib/yui/3.17.2/build/yui/yui-min.js
extension/ezjscore/design/standard/javascript/jquery-3.7.0.min.js
extension/community_design/design/suncana/javascript/jquery.ui.core.min.js
extension/community_design/design/suncana/javascript/jquery.ui.widget.min.js
extension/community_design/design/suncana/javascript/jquery.easing.1.3.js
extension/community_design/design/suncana/javascript/jquery.ui.tabs.js
extension/community_design/design/suncana/javascript/jquery.hoverIntent.min.js
extension/community_design/design/suncana/javascript/jquery.popmenu.js
extension/community_design/design/suncana/javascript/jScrollPane.js
extension/community_design/design/suncana/javascript/jquery.mousewheel.js
extension/community_design/design/suncana/javascript/jquery.cycle.all.js
extension/sevenx/design/simple/javascript/jquery.scrollTo.js
extension/community_design/design/suncana/javascript/jquery.cookie.js
extension/community_design/design/suncana/javascript/ezstarrating_jquery.js
extension/community_design/design/suncana/javascript/jquery.initboxes.js
extension/community_design/design/suncana/javascript/app.js
extension/community_design/design/suncana/javascript/twitterwidget.js
extension/community_design/design/suncana/javascript/community.js
extension/community_design/design/suncana/javascript/roadmap.js
extension/community_design/design/suncana/javascript/ez.js
extension/community_design/design/suncana/javascript/ezshareevents.js
extension/sevenx/design/simple/javascript/main.js

Templates used to render the page:

UsageRequested templateTemplateTemplate loadedEditOverride
1node/view/full.tplfull/forum_topic.tplextension/sevenx/design/simple/override/templates/full/forum_topic.tplEdit templateOverride template
6content/datatype/view/ezimage.tpl<No override>extension/sevenx/design/simple/templates/content/datatype/view/ezimage.tplEdit templateOverride template
6content/datatype/view/ezxmltext.tpl<No override>extension/community_design/design/suncana/templates/content/datatype/view/ezxmltext.tplEdit templateOverride template
7content/datatype/view/ezxmltags/paragraph.tpl<No override>extension/ezwebin/design/ezwebin/templates/content/datatype/view/ezxmltags/paragraph.tplEdit templateOverride template
3content/datatype/view/ezxmltags/literal.tpl<No override>extension/community/design/standard/templates/content/datatype/view/ezxmltags/literal.tplEdit templateOverride template
1pagelayout.tpl<No override>extension/sevenx/design/simple/templates/pagelayout.tplEdit templateOverride template
 Number of times templates used: 24
 Number of unique templates used: 6

Time used to render debug report: 0.0001 secs