예제 #1
0
 function search($searchText, $params = array(), $searchTypes = array())
 {
     eZDebug::createAccumulator('Search', 'eZ Find');
     eZDebug::accumulatorStart('Search');
     $error = 'Server not running';
     $asObjects = isset($params['AsObjects']) ? $params['AsObjects'] : true;
     //distributed search: fields to return can be specified in 2 parameters
     $params['FieldsToReturn'] = isset($params['FieldsToReturn']) ? $params['FieldsToReturn'] : array();
     if (isset($params['DistributedSearch']['returnfields'])) {
         $params['FieldsToReturn'] = array_merge($params['FieldsToReturn'], $params['DistributedSearch']['returnfields']);
     }
     $coreToUse = null;
     $shardQueryPart = null;
     if ($this->UseMultiLanguageCores === true) {
         $languages = $this->SiteINI->variable('RegionalSettings', 'SiteLanguageList');
         if (array_key_exists($languages[0], $this->SolrLanguageShards)) {
             $coreToUse = $this->SolrLanguageShards[$languages[0]];
             if ($this->FindINI->variable('LanguageSearch', 'SearchMainLanguageOnly') != 'enabled') {
                 $shardQueryPart = array('shards' => implode(',', $this->SolrLanguageShardURIs));
             }
         }
         //eZDebug::writeNotice( $languages, __METHOD__ . ' languages' );
         eZDebug::writeNotice($shardQueryPart, __METHOD__ . ' shards');
         //eZDebug::writeNotice( $this->SolrLanguageShardURIs, __METHOD__ . ' this languagesharduris' );
     } else {
         $coreToUse = $this->Solr;
     }
     if ($this->SiteINI->variable('SearchSettings', 'AllowEmptySearch') == 'disabled' && trim($searchText) == '') {
         $error = 'Empty search is not allowed.';
         eZDebug::writeNotice($error, __METHOD__);
         $resultArray = null;
     } else {
         eZDebug::createAccumulator('Query build', 'eZ Find');
         eZDebug::accumulatorStart('Query build');
         $queryBuilder = new ezfeZPSolrQueryBuilder($this);
         $queryParams = $queryBuilder->buildSearch($searchText, $params, $searchTypes);
         if (!$shardQueryPart == null) {
             $queryParams = array_merge($shardQueryPart, $queryParams);
         }
         eZDebug::accumulatorStop('Query build');
         eZDebugSetting::writeDebug('extension-ezfind-query', $queryParams, 'Final query parameters sent to Solr backend');
         eZDebug::createAccumulator('Engine time', 'eZ Find');
         eZDebug::accumulatorStart('Engine time');
         $resultArray = $coreToUse->rawSearch($queryParams);
         eZDebug::accumulatorStop('Engine time');
     }
     if ($resultArray) {
         $searchCount = $resultArray['response']['numFound'];
         $objectRes = $this->buildResultObjects($resultArray, $searchCount, $asObjects, $params);
         $stopWordArray = array();
         eZDebug::accumulatorStop('Search');
         return array('SearchResult' => $objectRes, 'SearchCount' => $searchCount, 'StopWordArray' => $stopWordArray, 'SearchExtras' => new ezfSearchResultInfo($resultArray));
     } else {
         eZDebug::accumulatorStop('Search');
         return array('SearchResult' => false, 'SearchCount' => 0, 'StopWordArray' => array(), 'SearchExtras' => new ezfSearchResultInfo(array('error' => ezpI18n::tr('ezfind', $error))));
     }
 }
     *
     * Stores the search engine instance which called the query builder.
     * Used to pass back some data to the search engine.
     *
     * @var Object
     * @see ezfeZPSolrQueryBuilder::ezfeZPSolrQueryBuilder
     */
    protected $searchPluginInstance;

    /**
     * Storing the default boolean operator used in building the 'fq' parameter
     *
     * @see ezfeZPSolrQueryBuilder::getBooleanOperatorFromFilter
     */
    const DEFAULT_BOOLEAN_OPERATOR = 'AND';
    const FACET_LIMIT = 20;
    const FACET_OFFSET = 0;
    const FACET_MINCOUNT = 1;
}

ezfeZPSolrQueryBuilder::$FindINI = eZINI::instance( 'ezfind.ini' );
ezfeZPSolrQueryBuilder::$SolrINI = eZINI::instance( 'solr.ini' );
ezfeZPSolrQueryBuilder::$SiteINI = eZINI::instance( 'site.ini' );
// need to refactor this: its only valid for the standard Solr request syntax, not for dismax based variants
// furthermore, negations should be added as well
ezfeZPSolrQueryBuilder::$allowedBooleanOperators = array( 'AND',
                                                          'and',
                                                          'OR',
                                                          'or' );
?>
예제 #3
0
    /**
     * More like this is pretty similar to normal search, but usually only the object or node id are sent to Solr
     * However, streams or a search text body can also be passed .. Solr will extract the important terms and build a
     * query for us
     *
     * @param string $queryType is one of 'noid', 'oid', 'url', 'text'
     * @param $queryValue the node id, object id, url or text body to use
     * @param array parameters. @see ezfeZPSolrQueryBuilder::buildMoreLikeThis()
     *
     * @return array List of eZFindResultNode objects.
     *
     * @todo: add functionality not to call the DB to recreate objects : $asObjects == false
     */
    function moreLikeThis( $queryType, $queryValue, $params = array() )
    {
        eZDebug::createAccumulator( 'MoreLikeThis', 'eZ Find' );
        eZDebug::accumulatorStart( 'MoreLikeThis' );
        $error = 'Server not running';
        $searchCount = 0;
        //mlt does not support distributed search yet, so find out which is
        //the language core to use and qyery only this one
        //search across languages does not make sense here
        $coreToUse = null;
        if ( $this->UseMultiLanguageCores == true )
        {
            $languages = $this->SiteINI->variable( 'RegionalSettings', 'SiteLanguageList' );
            if ( array_key_exists ( $languages[0], $this->SolrLanguageShards ) )
            {
                $coreToUse = $this->SolrLanguageShards[$languages[0]];
            }
        }
        else
        {
            $coreToUse = $this->Solr;
        }

        if ( trim( $queryType ) == '' || trim( $queryValue ) == '' )
        {
            $error = 'Missing query arguments for More Like This: ' . 'querytype = ' . $queryType . ', Query Value = ' . $queryValue;
            eZDebug::writeNotice( $error, __METHOD__ );
            $resultArray = null;
        }
        else
        {
            eZDebug::createAccumulator( 'Query build', 'eZ Find' );
            eZDebug::accumulatorStart( 'Query build' );
            $queryBuilder = new ezfeZPSolrQueryBuilder( $this );
            $queryParams = $queryBuilder->buildMoreLikeThis( $queryType, $queryValue, $params );
            eZDebug::accumulatorStop( 'Query build' );

            eZDebug::createAccumulator( 'Engine time', 'eZ Find' );
            eZDebug::accumulatorStart( 'Engine time' );
            $resultArray = $coreToUse->rawSolrRequest( '/mlt', $queryParams );
            eZDebug::accumulatorStop( 'Engine time' );
        }

        if ( !$resultArray )
        {
            eZDebug::accumulatorStop( 'Search' );
            return array(
                'SearchResult' => false,
                'SearchCount' => 0,
                'StopWordArray' => array(),
                'SearchExtras' => new ezfSearchResultInfo( array( 'error' => ezpI18n::tr( 'ezfind', $error ) ) ) );
        }
        $objectRes = array();
        if ( isset( $resultArray['response'] ) && is_array( $resultArray['response'] ) )
        {
            $result = $resultArray['response'];
            $searchCount = $result['numFound'];
            $maxScore = $result['maxScore'];
            $docs = $result['docs'];
            $localNodeIDList = array();
            $nodeRowList = array();

            // Loop through result, and get eZContentObjectTreeNode ID
            foreach ( $docs as $idx => $doc )
            {
                if ( $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'installation_id' )] == self::installationID() )
                {
                    $localNodeIDList[] = $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'main_node_id' )];
                }
            }

            if ( count( $localNodeIDList ) )
            {
                $tmpNodeRowList = eZContentObjectTreeNode::fetch( $localNodeIDList, false, false );
                // Workaround for eZContentObjectTreeNode::fetch behaviour
                if ( count( $localNodeIDList ) === 1 )
                {
                    $tmpNodeRowList = array( $tmpNodeRowList );
                }
                if ( $tmpNodeRowList )
                {
                    foreach ( $tmpNodeRowList as $nodeRow )
                    {
                        $nodeRowList[$nodeRow['node_id']] = $nodeRow;
                    }
                }
                unset( $tmpNodeRowList );
            }

            foreach ( $docs as $idx => $doc )
            {
                if ( $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'installation_id' )] == self::installationID() )
                {
                    // Search result document is from current installation
//                    var_dump( ezfSolrDocumentFieldBase::generateMetaFieldName( 'main_node_id' ), $doc, $nodeRowList );die();
                    $resultTree = new eZFindResultNode( $nodeRowList[$doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'main_node_id' )]] );
                    $resultTree->setContentObject( new eZContentObject( $nodeRowList[$doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'main_node_id' )]] ) );
                    $resultTree->setAttribute( 'is_local_installation', true );
                    // can_read permission must be checked as they could be out of sync in Solr, however, when called from template with:
                    // limitation, hash( 'accessWord', ... ) this check should not be performed as it has precedence.
                    // See: http://issues.ez.no/15978
                    if ( !isset( $params['Limitation'], $params['Limitation']['accessWord'] ) && !$resultTree->attribute( 'object' )->attribute( 'can_read' ) )
                    {
                        $searchCount--;
                        eZDebug::writeNotice( 'Access denied for eZ Find result, node_id: ' . $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'main_node_id' )], __METHOD__ );
                        continue;
                    }

                    $globalURL = $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'main_url_alias' )] .
                        '/(language)/' . $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'language_code' )];
                    eZURI::transformURI( $globalURL );
                }
                else
                {
                    $resultTree = new eZFindResultNode();
                    $resultTree->setAttribute( 'is_local_installation', false );
                    $globalURL = $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'installation_url' )] .
                        $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'main_url_alias' )] .
                        '/(language)/' . $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'language_code' )];
                }

                $resultTree->setAttribute( 'name', $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'name' )] );
                $resultTree->setAttribute( 'published', $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'published' )] );
                $resultTree->setAttribute( 'global_url_alias', $globalURL );
                $resultTree->setAttribute( 'highlight', isset( $highLights[$doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'guid' )]] ) ?
                                           $highLights[$doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'guid' )]] : null );
                $resultTree->setAttribute( 'score_percent', (int) ( ( $doc['score'] / $maxScore ) * 100 ) );
                $resultTree->setAttribute( 'language_code', $doc[ezfSolrDocumentFieldBase::generateMetaFieldName( 'language_code' )] );
                $objectRes[] = $resultTree;
            }
        }

        $stopWordArray = array();

        eZDebug::accumulatorStop( 'Search' );
        eZDebug::writeDebug( $resultArray['interestingTerms'], 'MoreLikeThis terms' );
        return array(
            'SearchResult' => $objectRes,
            'SearchCount' => $searchCount,
            'StopWordArray' => $stopWordArray,
            'SearchExtras' => new ezfSearchResultInfo( $resultArray ) );
    }
예제 #4
0
 /**
  * More like this is pretty similar to normal search, but usually only the object or node id are sent to Solr
  * However, streams or a search text body can also be passed .. Solr will extract the important terms and build a
  * query for us
  *
  * @param string $queryType is one of 'noid', 'oid', 'url', 'text'
  * @param $queryValue the node id, object id, url or text body to use
  * @param array parameters. @see ezfeZPSolrQueryBuilder::buildMoreLikeThis()
  *
  * @return array List of eZFindResultNode objects.
  *
  * @todo: add functionality not to call the DB to recreate objects : $asObjects == false
  */
 function moreLikeThis($queryType, $queryValue, $params = array())
 {
     eZDebug::createAccumulator('MoreLikeThis', 'eZ Find');
     eZDebug::accumulatorStart('MoreLikeThis');
     $error = 'Server not running';
     $asObjects = isset($params['AsObjects']) ? $params['AsObjects'] : true;
     //mlt does not support distributed search yet, so find out which is
     //the language core to use and qyery only this one
     //search across languages does not make sense here
     $coreToUse = null;
     if ($this->UseMultiLanguageCores == true) {
         $languages = $this->SiteINI->variable('RegionalSettings', 'SiteLanguageList');
         if (array_key_exists($languages[0], $this->SolrLanguageShards)) {
             $coreToUse = $this->SolrLanguageShards[$languages[0]];
         }
     } else {
         $coreToUse = $this->Solr;
     }
     if (trim($queryType) == '' || trim($queryValue) == '') {
         $error = 'Missing query arguments for More Like This: ' . 'querytype = ' . $queryType . ', Query Value = ' . $queryValue;
         eZDebug::writeNotice($error, __METHOD__);
         $resultArray = null;
     } else {
         eZDebug::createAccumulator('Query build', 'eZ Find');
         eZDebug::accumulatorStart('Query build');
         $queryBuilder = new ezfeZPSolrQueryBuilder($this);
         $queryParams = $queryBuilder->buildMoreLikeThis($queryType, $queryValue, $params);
         eZDebug::accumulatorStop('Query build');
         eZDebug::createAccumulator('Engine time', 'eZ Find');
         eZDebug::accumulatorStart('Engine time');
         $resultArray = $coreToUse->rawSolrRequest('/mlt', $queryParams);
         eZDebug::accumulatorStop('Engine time');
     }
     if ($resultArray) {
         $searchCount = $resultArray['response']['numFound'];
         $objectRes = $this->buildResultObjects($resultArray, $searchCount, $asObjects);
         $stopWordArray = array();
         eZDebugSetting::writeDebug('extension-ezfind-query-mlt', $resultArray['interestingTerms'], 'MoreLikeThis terms');
         return array('SearchResult' => $objectRes, 'SearchCount' => $searchCount, 'StopWordArray' => $stopWordArray, 'SearchExtras' => new ezfSearchResultInfo($resultArray));
     } else {
         return array('SearchResult' => false, 'SearchCount' => 0, 'StopWordArray' => array(), 'SearchExtras' => new ezfSearchResultInfo(array('error' => ezpI18n::tr('ezfind', $error))));
     }
 }
 /**
  * Simple wrapper that makes buildSortParameter public
  **/
 public function buildSortParameter($parameterList)
 {
     return parent::buildSortParameter($parameterList);
 }
 /**
  * @dataProvider providerTestQuoteIfNeeded
  **/
 public function testQuoteIfNeeded($value, $expected)
 {
     self::assertEquals($expected, ezfeZPSolrQueryBuilder::quoteIfNeeded($value));
 }