Chad has submitted this change and it was merged.

Change subject: Boost perfect phrase matches.
......................................................................


Boost perfect phrase matches.

If the user hasn't enclosed anything in quotes then we assume that they
would like a perfect phrase match if one exists.  This patch rescores
the top bunch of results with a copy of the original query as a phrase
query.

Change-Id: I05f7dcf5fac1223336b3191d18dc084b4bad7232
---
M CirrusSearch.php
M CirrusSearchSearcher.php
2 files changed, 44 insertions(+), 3 deletions(-)

Approvals:
  Chad: Verified; Looks good to me, approved
  jenkins-bot: Checked



diff --git a/CirrusSearch.php b/CirrusSearch.php
index 989b222..654a494 100644
--- a/CirrusSearch.php
+++ b/CirrusSearch.php
@@ -43,6 +43,20 @@
 // Number of replicas per shard for each index
 $wgCirrusSearchContentReplicaCount = array( 'content' => 2, 'general' => 2 );
 
+// When searching for a phrase how many words not searched for can be in the 
phrase
+// before it doesn't match. If I search for "like yellow candy" then 
phraseSlop of 0
+// won't match "like brownish yellow candy" but phraseSlop of 1 will.
+$wgCirrusSearchPhraseSlop = 1;
+
+// If the search doesn't include any phrases (delimited by quotes) then we try 
wrapping
+// the whole thing in quotes because sometimes that can turn up better 
results. This is
+// the boost that we give such matches. Set this less than or equal to 1.0 to 
turn off
+// this feature.
+$wgCirrusSearchPhraseRescoreBoost = 10.0;
+
+// Number of documents for which automatic phrase matches are performed if it 
is enabled.
+$wgCirrusSearchPhraseRescoreWindowSize = 1024;
+
 // If true CirrusSearch asks Elasticsearch to perform searches using a mode 
that should
 // product more accurate results at the cost of performance. See this for more 
info:
 // 
http://www.elasticsearch.org/blog/understanding-query-then-fetch-vs-dfs-query-then-fetch/
diff --git a/CirrusSearchSearcher.php b/CirrusSearchSearcher.php
index 44ae9d0..2afb534 100644
--- a/CirrusSearchSearcher.php
+++ b/CirrusSearchSearcher.php
@@ -53,6 +53,7 @@
        private $query = null;
        private $filters = array();
        private $suggest = null;
+       private $rescore = null;
        /**
         * @var string description of the current operation used in logging 
errors
         */
@@ -103,6 +104,9 @@
         */
        public function searchText( $term, $showRedirects ) {
                global $wgCirrusSearchWeights;
+               global $wgCirrusSearchPhraseSlop;
+               global $wgCirrusSearchPhraseRescoreBoost;
+               global $wgCirrusSearchPhraseRescoreWindowSize;
                global $wgCirrusSearchPhraseSuggestMaxErrors;
                global $wgCirrusSearchPhraseSuggestConfidence;
                wfDebugLog( 'CirrusSearch', "Searching:  $term" );
@@ -138,7 +142,8 @@
 
                // Actual text query
                if ( trim( $term ) !== '' || $extraQueryStrings ) {
-                       $queryStringQueryString = trim( implode( ' ', 
$extraQueryStrings ) . ' ' . self::fixupQueryString( $term ) );
+                       $fixedTerm = self::fixupQueryString( $term );
+                       $queryStringQueryString = trim( implode( ' ', 
$extraQueryStrings ) . ' ' . $fixedTerm );
                        $this->query = new \Elastica\Query\QueryString( 
$queryStringQueryString );
                        $fields = array(
                                'title^' . $wgCirrusSearchWeights[ 'title' ],
@@ -150,9 +155,23 @@
                        }
                        $this->query->setFields( $fields );
                        $this->query->setAutoGeneratePhraseQueries( true );
-                       $this->query->setPhraseSlop( 3 );
+                       $this->query->setPhraseSlop( $wgCirrusSearchPhraseSlop 
);
                        $this->query->setDefaultOperator( 'AND' );
-                       // TODO phrase match boosts?
+
+                       // Only do a phrase match rescore if the query doesn't 
include any phrases
+                       if ( $wgCirrusSearchPhraseRescoreBoost > 1.0 && 
!preg_match( '/"[^ "]+ [^"]+"/', $fixedTerm ) ) {
+                               $this->rescore = array(
+                                       'window_size' => 
$wgCirrusSearchPhraseRescoreWindowSize,
+                                       'query' => array(
+                                               'rescore_query' => 
$this->query->toArray(),
+                                               'query_weight' => 1.0,
+                                               'rescore_query_weight' => 
$wgCirrusSearchPhraseRescoreBoost,
+                                       )
+                               );
+                               // Replace the original query string with a 
quoted copy
+                               $this->rescore[ 'query' ][ 'rescore_query' ][ 
'query_string' ][ 'query' ] = '"' . $fixedTerm . '"';
+                       }
+
                        $this->suggest = array(
                                'text' => $term,
                                self::PHRASE_TITLE => array(
@@ -266,6 +285,12 @@
                if( $this->limit ) {
                        $query->setSize( $this->limit );
                }
+               if ( $this->rescore ) {
+                       // Wrap the rescore query in the boostQuery just as we 
wrap the regular query.
+                       $this->rescore[ 'query' ][ 'rescore_query' ] =
+                               self::boostQuery( $this->rescore[ 'query' ][ 
'rescore_query' ] )->toArray();
+                       $query->setParam( 'rescore', $this->rescore );
+               }
 
                if ( $this->namespaces ) {
                        $this->filters[] = new \Elastica\Filter\Terms( 
'namespace', $this->namespaces );
@@ -366,6 +391,8 @@
                                :|              (?# no specifying your own 
fields)
                                \\\
                        )/x', '\\\$1', $string );
+               // If the string doesn't have balanced quotes then add a quote 
on the end so Elasticsearch
+               // can parse it.
                if ( !preg_match( '/^(
                                [^"]|                   (?# non quoted terms)
                                "([^"]|\\.)*"   (?# quoted terms)

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I05f7dcf5fac1223336b3191d18dc084b4bad7232
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/CirrusSearch
Gerrit-Branch: master
Gerrit-Owner: Manybubbles <[email protected]>
Gerrit-Reviewer: Chad <[email protected]>
Gerrit-Reviewer: Manybubbles <[email protected]>
Gerrit-Reviewer: jenkins-bot

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

Reply via email to