| Current File : /home/jvzmxxx/wiki1/extensions/Flow/includes/Search/SearchEngine.php |
<?php
namespace Flow\Search;
use Elastica\Filter\BoolFilter;
use Elastica\Filter\Terms;
use Elastica\Query;
use Flow\Exception\InvalidParameterException;
class SearchEngine extends \SearchEngine {
/**
* @var int
*/
const MAX_OFFSET = 100000;
/**
* @var string|false $type Type of revisions to retrieve
*/
protected $type = false;
/**
* Unlike \SearchEngine, the default is *no* specific namespace (=ALL)
*
* @var int[]
*/
public $namespaces = array();
/**
* @var int[]
*/
protected $pageIds = array();
/**
* @var string[]
*/
protected $moderationStates = array();
/**
* @var string
*/
protected $sort = 'relevance';
/**
* @param string $term text to search
* @return \Status
*/
public function searchText( $term ) {
$term = trim( $term );
// No searching for nothing! That takes forever!
if ( !$term ) {
return null;
}
$query = new Query();
$offset = min( $this->offset, static::MAX_OFFSET );
if ( $offset ) {
$query->setFrom( $offset );
}
if ( $this->limit ) {
$query->setSize( $this->limit );
}
$filter = new BoolFilter();
// filters
if ( $this->namespaces ) {
$filter->addMust( new Terms( 'namespace', $this->namespaces ) );
}
if ( $this->pageIds ) {
$filter->addMust( new Terms( 'pageid', $this->pageIds ) );
}
if ( $this->moderationStates ) {
$filter->addMust( new Terms( 'revisions.moderation_state', $this->moderationStates ) );
}
// only apply filters if there are any
if ( $filter->toArray() ) {
$query->setPostFilter( $filter );
}
$sortArgs = $this->getSortArgs();
if ( isset( $sortArgs[$this->sort] ) && $sortArgs[$this->sort] ) {
$query->setSort( $sortArgs[$this->sort] );
}
// @todo: interwiki stuff? (see \CirrusSearch)
$searcher = new Searcher( $query, false, $this->type );
return $searcher->searchText( $term );
}
/**
* Set the search index to search in.
* false is allowed (means we'll search *all* types)
*
* @param string|false $type
* @throws InvalidParameterException
*/
public function setType( $type ) {
$allowedTypes = array_merge( Connection::getAllTypes(), array( false ) );
if ( !in_array( $type, $allowedTypes ) ) {
throw new InvalidParameterException( 'Invalid search index requested' );
}
$this->type = $type;
}
/**
* Set pages in which to search.
*
* @param int[] $pageIds
*/
public function setPageIds( array $pageIds ) {
$this->pageIds = $pageIds;
}
/**
* Set moderation states in which to search.
*
* @param string[] $moderationStates
*/
public function setModerationStates( array $moderationStates = array() ) {
$this->moderationStates = $moderationStates;
}
/**
* @param string $sort
* @throws InvalidParameterException
*/
public function setSort( $sort ) {
if ( !in_array( $sort, $this->getValidSorts() ) ) {
throw new InvalidParameterException( 'Invalid search sort requested' );
}
$this->sort = $sort;
}
/**
* Get the sort of sorts we allow.
*
* @return array
*/
public function getValidSorts() {
// note that API will default to the first sort in this array - make it
// a sensible default!
return array_keys( $this->getSortArgs() );
}
/**
* We may want to revisit this at some later point.
*
* Nik's advice: "I advise against asking Elasticsearch to sort.
* Instead layer some kind of boost for more recent posts on top of the
* standard text scoring. That way better matches will still get sorted
* higher, even if they are older. Also, sorting isn't super efficient
* in Elasticsearch."
*
* @see https://gerrit.wikimedia.org/r/#/c/126996/6/includes/Search/SearchEngine.php
* @return array [description => [sort field => order]]
*/
public function getSortArgs() {
return array(
'relevance' => array( /* default */ ),
'timestamp_asc' => array( 'timestamp' => 'asc' ),
'timestamp_desc' => array( 'timestamp' => 'desc' ),
'update_timestamp_asc' => array( 'update_timestamp' => 'asc' ),
'update_timestamp_desc' => array( 'update_timestamp' => 'desc' ),
);
}
/**
* {@inheritDoc}
*/
public function supports( $feature ) {
// we're not really an alternative search engine for MW ;)
return false;
}
}