41 private const RTI_CHUNK_SIZE = 500;
44 parent::__construct();
45 $this->
addDescription(
'Rebuild search index table from scratch' );
49 return Maintenance::DB_ADMIN;
55 if ( $dbw->getType() ==
'postgres' ) {
56 $this->
fatalError(
"This script is not needed when using Postgres.\n" );
59 if ( $dbw->getType() ==
'sqlite' ) {
60 if ( !DatabaseSqlite::getFulltextSearchModule() ) {
61 $this->
fatalError(
"Your version of SQLite module for PHP doesn't "
62 .
"support full-text search (FTS3).\n" );
66 if ( $dbw->getType() ==
'mysql' ) {
67 $this->dropMysqlTextIndex();
68 $this->clearSearchIndex();
70 $this->createMysqlTextIndex();
72 $this->clearSearchIndex();
76 $this->
output(
"Done.\n" );
84 $res = $dbw->newSelectQueryBuilder()
85 ->select( [
'count' =>
'MAX(page_id)' ] )
87 ->caller( __METHOD__ )->fetchResultSet();
88 $s = $res->fetchObject();
90 $this->
output(
"Rebuilding index fields for {$count} pages...\n" );
94 $queryBuilderTemplate = $revStore->newSelectQueryBuilder( $dbw )
98 while ( $n < $count ) {
100 $this->
output( $n .
"\n" );
102 $end = $n + self::RTI_CHUNK_SIZE - 1;
103 $queryBuilder = clone $queryBuilderTemplate;
104 $res = $queryBuilder->where( [
105 $dbw->expr(
'page_id',
'>=', $n )->and(
'page_id',
'<=', $end ),
106 'page_latest = rev_id'
107 ] )->caller( __METHOD__ )->fetchResultSet();
109 foreach ( $res as $s ) {
112 if ( $s->page_namespace < 0 ) {
116 $title = Title::makeTitle( $s->page_namespace, $s->page_title );
118 $revRecord = $revStore->newRevisionFromRow( $s );
119 $content = $revRecord->getContent( SlotRecord::MAIN );
124 $this->
output(
"Failed to deserialize content of revision {$s->rev_id} of page "
125 .
"`" . $title->getPrefixedDBkey() .
"`!\n" );
128 $n += self::RTI_CHUNK_SIZE;
135 private function dropMysqlTextIndex() {
137 $searchindex = $dbw->tableName(
'searchindex' );
138 if ( $dbw->indexExists(
'searchindex',
'si_title', __METHOD__ ) ) {
139 $this->
output(
"Dropping index...\n" );
140 $sql =
"ALTER TABLE $searchindex DROP INDEX si_title, DROP INDEX si_text";
141 $dbw->query( $sql, __METHOD__ );
148 private function createMysqlTextIndex() {
150 $searchindex = $dbw->tableName(
'searchindex' );
151 $this->
output(
"\nRebuild the index...\n" );
152 foreach ( [
'si_title',
'si_text' ] as $field ) {
153 $sql =
"ALTER TABLE $searchindex ADD FULLTEXT $field ($field)";
154 $dbw->query( $sql, __METHOD__ );
161 private function clearSearchIndex() {
163 $this->
output(
'Clearing searchindex table...' );
164 $dbw->newDeleteQueryBuilder()
165 ->deleteFrom(
'searchindex' )
167 ->caller( __METHOD__ )->execute();
168 $this->
output(
"Done\n" );
Exception representing a failure to serialize or unserialize a content object.
Rebuild search index table from scratch.
getDbType()
Does the script need different DB access? By default, we give Maintenance scripts normal rights to th...
populateSearchIndex()
Populates the search index with content from all pages.