Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 55 |
MetaNamespaceStore | |
0.00% |
0 / 1 |
|
0.00% |
0 / 7 |
132 | |
0.00% |
0 / 55 |
__construct | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
docId | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 5 |
|||
buildIndexProperties | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 9 |
|||
reindex | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 9 |
|||
find | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 8 |
|||
queryFilter | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
buildDocuments | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 17 |
<?php | |
namespace CirrusSearch\MetaStore; | |
use Elastica\Document; | |
use Elastica\Index; | |
use Elastica\Query\BoolQuery; | |
use Elastica\Query\Ids; | |
use Elastica\Query\MatchQuery; | |
use WikiMap; | |
class MetaNamespaceStore implements MetaStore { | |
/** @const Value of metastore 'type' field for our documents */ | |
public const METASTORE_TYPE = 'namespace'; | |
/** @var Index */ | |
private $index; | |
/** @var string */ | |
private $wikiId; | |
public function __construct( Index $index, $wikiId = null ) { | |
$this->index = $index; | |
$this->wikiId = $wikiId ?? WikiMap::getCurrentWikiId(); | |
} | |
/** | |
* @param string $wikiId Wiki namespace belongs to | |
* @param int $nsId Id of the namespace | |
* @return string Metastore document id | |
*/ | |
public static function docId( $wikiId, $nsId ) { | |
return implode( '-', [ | |
self::METASTORE_TYPE, | |
$wikiId, $nsId | |
] ); | |
} | |
/** | |
* @return array Custom field mappings for metastore index | |
*/ | |
public function buildIndexProperties() { | |
return [ | |
'namespace_name' => [ | |
'type' => 'text', | |
'analyzer' => 'near_match_asciifolding', | |
'norms' => false, | |
'index_options' => 'docs', | |
], | |
]; | |
} | |
/** | |
* Delete and re-index all namespaces for current wiki | |
* | |
* @param \Language $lang Content language of the wiki | |
*/ | |
public function reindex( \Language $lang ) { | |
$documents = $this->buildDocuments( $lang ); | |
$docIds = []; | |
foreach ( $documents as $doc ) { | |
$docIds[] = $doc->getId(); | |
} | |
$this->index->deleteByQuery( \Elastica\Query::create( | |
$this->queryFilter()->addMustNot( new Ids( $docIds ) ) ) ); | |
$this->index->addDocuments( $documents ); | |
} | |
/** | |
* Find namespaces on the current wiki very similar to $name. | |
* Invoking from a user request must be gated on a PoolCounter. | |
* | |
* @param string $name Namespace to search for | |
* @param array $queryOptions Query parameters to send to elasticsearch | |
* @return \Elastica\ResultSet | |
*/ | |
public function find( $name, array $queryOptions = [] ) { | |
$bool = $this->queryFilter(); | |
$bool->addMust( ( new MatchQuery() ) | |
->setField( 'namespace_name', $name ) ); | |
$query = ( new \Elastica\Query( $bool ) ) | |
->setParam( '_source', [ 'namespace_id' ] ) | |
->setParam( 'stats', [ 'namespace' ] ); | |
return $this->index->search( $query, $queryOptions ); | |
} | |
private function queryFilter() { | |
return ( new BoolQuery() ) | |
->addFilter( new MatchQuery( 'type', self::METASTORE_TYPE ) ) | |
->addFilter( new MatchQuery( 'wiki', $this->wikiId ) ); | |
} | |
private function buildDocuments( \Language $lang ) { | |
$namesByNsId = []; | |
foreach ( $lang->getNamespaceIds() as $name => $nsId ) { | |
if ( $name ) { | |
$namesByNsId[$nsId][] = $name; | |
} | |
} | |
$documents = []; | |
foreach ( $namesByNsId as $nsId => $names ) { | |
$documents[] = new Document( self::docId( $this->wikiId, $nsId ), [ | |
'type' => self::METASTORE_TYPE, | |
'wiki' => $this->wikiId, | |
'namespace_id' => $nsId, | |
'namespace_name' => $names, | |
], '_doc' ); | |
} | |
return $documents; | |
} | |
} |