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
