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' ); ?>
/** * 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 ) ); }
/** * 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)); }