Chad has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/91995


Change subject: Implement interwiki searches
......................................................................

Implement interwiki searches

This is a completely untested proof of concept

Change-Id: Icc8529567bd6dd372d2493cd5d749db93c1f7552
---
M CirrusSearch.php
M includes/CirrusSearchResultSet.php
M includes/CirrusSearchResultsType.php
M includes/CirrusSearchSearcher.php
4 files changed, 83 insertions(+), 8 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CirrusSearch 
refs/changes/95/91995/1

diff --git a/CirrusSearch.php b/CirrusSearch.php
index 69d4aa0..242a2f2 100644
--- a/CirrusSearch.php
+++ b/CirrusSearch.php
@@ -123,6 +123,15 @@
 // Changing it requires an in place reindex to take effect.  Currently only 
available in English.
 $wgCirrusSearchUseAggressiveSplitting = true;
 
+// Configuration for interwiki searching
+// Array where the key is the index prefix (most like db prefix)
+//  and the value is the interwiki prefix to use.
+//  (e.g. $wgCirrusSearchInterwiki['enwiki'] = 'w'
+$wgCirrusSearchInterwiki = array();
+
+// How long to cache interwiki searches for (in seconds)
+$wgCirrusSearchInterwikiCacheTime = 60 * 60 * 3;
+
 $includes = __DIR__ . "/includes/";
 /**
  * Classes
diff --git a/includes/CirrusSearchResultSet.php 
b/includes/CirrusSearchResultSet.php
index 16e75f9..e809fd1 100644
--- a/includes/CirrusSearchResultSet.php
+++ b/includes/CirrusSearchResultSet.php
@@ -28,6 +28,7 @@
        private static $suggestionHighlightPostEscaped = null;
 
        private $result, $hits, $totalHits, $suggestionQuery, 
$suggestionSnippet;
+       private $interwikiResults;
 
        public function __construct( $res ) {
                $this->result = $res;
@@ -118,5 +119,10 @@
        }
 
        public function getInterwikiResults() {
+               return $this->interwikiResults;
+       }
+
+       public function setInterwikiResults( CirrusSearchResultSet $res ) {
+               $this->interwikiResults = $res;
        }
 }
diff --git a/includes/CirrusSearchResultsType.php 
b/includes/CirrusSearchResultsType.php
index cc686ed..52bd43b 100644
--- a/includes/CirrusSearchResultsType.php
+++ b/includes/CirrusSearchResultsType.php
@@ -71,6 +71,6 @@
        }
 
        public function transformElasticsearchResult( $result ) {
-               return new CirrusSearchResultSet( $result );
+               return $result ? new CirrusSearchResultSet( $result ) : null;
        }
 }
diff --git a/includes/CirrusSearchSearcher.php 
b/includes/CirrusSearchSearcher.php
index 82c7c0d..a0849d8 100644
--- a/includes/CirrusSearchSearcher.php
+++ b/includes/CirrusSearchSearcher.php
@@ -350,18 +350,60 @@
 
                // Perform the search
                $description = $this->description;
+               $resultsType = $this->resultsType;
                $indexType = $this->pickIndexTypeFromNamespaces();
+               $interwikiIndexName = $this->getInterwikiIndexName();
                $work = new PoolCounterWorkViaCallback( 'CirrusSearch-Search', 
"_elasticsearch", array(
-                       'doWork' => function() use ( $indexType, $query, 
$queryOptions, $description ) {
+                       // The core search work is done in this function
+                       'doWork' => function() use ( $indexType, 
$interwikiIndexName, $query, $queryOptions, $description, $resultsType ) {
+                               $result = array( 'local' => null, 'interwiki' 
=> null );
+
+                               // Local searches
                                try {
-                                       $result = 
CirrusSearchConnection::getPageType( $indexType )
-                                               ->search( $query, $queryOptions 
);
-                                       wfDebugLog( 'CirrusSearch', 'Search 
completed in ' . $result->getTotalTime() . ' millis' );
-                                       return $result;
+                                       $result['local'] = 
CirrusSearchConnection::getPageType( $indexType )
+                                                       ->search( $query, 
$queryOptions );
                                } catch ( 
\Elastica\Exception\ExceptionInterface $e ) {
                                        wfLogWarning( "Search backend error 
during $description.  Error message is:  " . $e->getMessage() );
                                        return false;
                                }
+
+                               // Potentially do interwiki searches
+                               if ( $interwikiIndexName && $resultsType 
instanceof CirrusSearchFullTextResultsType ) {
+                                       global 
$wgCirrusSearchInterwikiCacheTime, $wgMemc;
+
+                                       $iwkey = wfMemcKey( 'cirrus', 
'interwiki', $interwikiIndexName );
+                                       $iwres = $wgMemc->get( $iwkey );
+                                       if ( !$iwres ) {
+                                               try {
+                                                       $iwres = 
CirrusSearchConnection::getPageType( $indexType, $interwikiIndexName )
+                                                               ->search( 
$query, $queryOptions );
+                                               } catch ( 
\Elastica\Exception\ExceptionInterface $e ) {
+                                                       // Log the warning, but 
IW search failure shouldn't cause total
+                                                       // search failure
+                                                       $iwres = null;
+                                                       wfLogWarning( "Search 
backend error during $description (interwiki)."
+                                                               . " Error 
message is:  " . $e->getMessage() );
+                                               }
+                                       }
+                                       if ( $iwres ) {
+                                               $wgMec->set( $iwkey, $iwres, 
$wgCirrusSearchInterwikiCacheTime );
+                                       }
+                                       $result['interwiki'] = $iwres;
+                               }
+                               wfDebugLog( 'CirrusSearch', 'Search completed 
in ' . $result->getTotalTime() . ' millis' );
+                               return $result;
+                       },
+                       // Since we potentially cache interwiki results, 
sometimes we can return at least
+                       // some results when we're overloaded
+                       'doCachedWork' => function() use( $interwikiIndexName, 
$resultsType ) {
+                               global $wgMemc;
+                               if ( $interwikiIndexName && $resultsType 
instanceof CirrusSearchFullTextResultsType ) {
+                                       $iwres = $wgMemc->get( wfMemcKey( 
'cirrus', 'interwiki', $interwikiIndexName ) );
+                                       if( $iwres ) {
+                                               return array( 'local' => null, 
'interwiki' => $iwres );
+                                       }
+                               }
+                               return false;
                        }
                ) );
                $result = $work->execute();
@@ -370,9 +412,14 @@
                        $status->warning( 'cirrussearch-backend-error' );
                        return $status;
                }
-               $result = $this->resultsType->transformElasticsearchResult( 
$result );
+               $resultSet = $this->resultsType->transformElasticsearchResult( 
$result['local'] );
+               if ( $result['interwiki'] ) {
+                       $resultSet->setInterwikiResults(
+                               
$this->resultsType->transformElasticsearchResult( $result['interwiki'] )
+                       );
+               }
                wfProfileOut( __METHOD__ );
-               return $result;
+               return $localresult;
        }
 
        private function buildSearchTextQuery( $fields, $query ) {
@@ -458,6 +505,19 @@
                        CirrusSearchConnection::GENERAL_INDEX_TYPE;
        }
 
+       /**
+        * Get us a list of interwiki indexes we can search
+        * @return string
+        */
+       private function getInterwikiIndexName() {
+               global $wgCirrusSearchInterwiki;
+               if ( $wgCirrusSearchInterwiki ) {
+                       return implode( ',', $wgCirrusSearchInterwiki );
+               } else {
+                       return '';
+               }
+       }
+
        private function buildPrefixFilter( $search ) {
                $match = new \Elastica\Query\Match();
                $match->setField( 'title.prefix', array(

-- 
To view, visit https://gerrit.wikimedia.org/r/91995
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Icc8529567bd6dd372d2493cd5d749db93c1f7552
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CirrusSearch
Gerrit-Branch: master
Gerrit-Owner: Chad <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to