jenkins-bot has submitted this change and it was merged.
Change subject: Fix suggestion queries containing a space.
......................................................................
Fix suggestion queries containing a space.
Do this by switching from a prefix search of the analyzed title to a
match of the lightly analyzed title with the edgengram analyzed title.
This mimics the current functionality.
It also handles lower casing very well so things with accents aren't
surprisingly lost.
Change-Id: I513b0b1aa35896ba346e48aa2e657f1f6447c625
---
M CirrusSearch.body.php
M CirrusSearch.php
M updateSearchConfig.php
3 files changed, 78 insertions(+), 10 deletions(-)
Approvals:
Demon: Looks good to me, approved
jenkins-bot: Verified
diff --git a/CirrusSearch.body.php b/CirrusSearch.body.php
index 5ef2cbe..ef62cf7 100644
--- a/CirrusSearch.body.php
+++ b/CirrusSearch.body.php
@@ -23,6 +23,13 @@
const HIGHLIGHT_PRE = '<span class="searchmatch">';
const HIGHLIGHT_POST = '</span>';
const PAGE_TYPE_NAME = 'page';
+ /**
+ * Maximum title length that we'll check in prefix search. Since
titles can
+ * be 255 bytes in length we're setting this to 255 characters but this
+ * might cause bloat in the title's prefix index so we'll have to keep
an
+ * eye on this.
+ */
+ const MAX_PREFIX_SEARCH = 255;
/**
* Singleton instance of the client
@@ -90,7 +97,12 @@
// Query params
$query->setLimit( $limit );
$query->setFilter( CirrusSearch::buildNamespaceFilter( $ns ) );
- $query->setQuery( new \Elastica\Query\Prefix( array( 'title' =>
strtolower( $search ) ) ) );
+ $match = new \Elastica\Query\Match();
+ $match->setField( 'title.prefix', array(
+ 'query' => substr( $search, 0,
CirrusSearch::MAX_PREFIX_SEARCH ),
+ 'analyzer' => 'prefix_query'
+ ) );
+ $query->setQuery( $match );
// Perform the search
$work = new PoolCounterWorkViaCallback( 'CirrusSearch-Search',
"_elasticsearch", array(
diff --git a/CirrusSearch.php b/CirrusSearch.php
index 5c8408a..06d9655 100644
--- a/CirrusSearch.php
+++ b/CirrusSearch.php
@@ -107,6 +107,7 @@
$wgAutoloadClasses['Elastica\Query\AbstractQuery'] = $elasticaDir .
'Query/AbstractQuery.php';
$wgAutoloadClasses['Elastica\Query\Field'] = $elasticaDir . 'Query/Field.php';
$wgAutoloadClasses['Elastica\Query\MatchAll'] = $elasticaDir .
'Query/MatchAll.php';
+$wgAutoloadClasses['Elastica\Query\Match'] = $elasticaDir . 'Query/Match.php';
$wgAutoloadClasses['Elastica\Query\Prefix'] = $elasticaDir .
'Query/Prefix.php';
$wgAutoloadClasses['Elastica\Query\QueryString'] = $elasticaDir .
'Query/QueryString.php';
$wgAutoloadClasses['Elastica\Transport\AbstractTransport'] = $elasticaDir .
'Transport/AbstractTransport.php';
diff --git a/updateSearchConfig.php b/updateSearchConfig.php
index 5717985..fb5ba40 100644
--- a/updateSearchConfig.php
+++ b/updateSearchConfig.php
@@ -310,13 +310,33 @@
'text' => $this->buildTextAnalyzer(),
'suggest' => array_merge(
$this->buildTextAnalyzer(), array(
'filter' => array(
'suggest_shingle' )
- ) )
+ ) ),
+ 'prefix' => array(
+ 'type' => 'custom',
+ 'tokenizer' => 'prefix',
+ 'filter' => 'lowercase'
+ ),
+ 'prefix_query' => array(
+ 'type' => 'custom',
+ 'tokenizer' => 'no_splitting',
+ 'filter' => 'lowercase'
+ )
),
'filter' => array(
'suggest_shingle' => array(
'type' => 'shingle',
'min_shingle_size' => 2,
'max_shingle_size' => 5
+ ),
+ 'lowercase' =>
$this->buildLowercaseFilter()
+ ),
+ 'tokenizer' => array(
+ 'prefix' => array(
+ 'type' => 'edgeNGram',
+ 'max_gram' =>
CirrusSearch::MAX_PREFIX_SEARCH
+ ),
+ 'no_splitting' => array( // Just grab
the whole term.
+ 'type' => 'keyword'
)
)
)
@@ -332,29 +352,64 @@
}
}
+ /**
+ * Build a lowercase filter. The filter is customized to the wiki's
language.
+ */
+ private function buildLowercaseFilter() {
+ $filter = array(
+ 'type' => 'lowercase'
+ );
+ // At present there are only two language codes that support
any customization
+ // beyond the defaults: greek and turkish.
+ global $wgLanguageCode;
+ switch ($wgLanguageCode) {
+ case 'el':
+ $filter['language'] = 'greek';
+ break;
+ case 'tr':
+ $filter['language'] = 'turkish';
+ break;
+ }
+ return $filter;
+ }
+
private function buildPageMappings() {
// Note never to set something as type='object' here because
that isn't returned by elasticsearch
// and is infered anyway.
return array(
- 'title' => $this->buildFieldWithSuggest( 'title' ),
- 'text' => $this->buildFieldWithSuggest( 'text' ),
- 'category' => array( 'type' => 'string', 'analyzer' =>
'text' ),
+ 'title' => $this->buildStringField( 'title', array(
'suggest', 'prefix' ) ),
+ 'text' => $this->buildStringField( 'text', array(
'suggest' ) ),
+ 'category' => $this->buildStringField(),
'redirect' => array(
'properties' => array(
- 'title' => array( 'type' => 'string',
'analyzer' => 'text' )
+ 'title' => $this->buildStringField()
)
)
);
}
- private function buildFieldWithSuggest( $name ) {
- return array(
+ /**
+ * Build a string field.
+ * @param name string Name of the field. Required if extra is not
falsy.
+ * @param extra array Extra analyzers for this field beyond the basic
string type. If not falsy the
+ * field will be a multi_field.
+ * @return array definition of the field
+ */
+ private function buildStringField( $name = null, $extra = null ) {
+ $field = array( 'type' => 'string', 'analyzer' => 'text' );
+ if ( !$extra ) {
+ return $field;
+ }
+ $field = array(
'type' => 'multi_field',
'fields' => array(
- $name => array( 'type' => 'string', 'analyzer'
=> 'text' ),
- 'suggest' => array( 'type' => 'string',
'analyzer' => 'suggest' )
+ $name => $field
)
);
+ foreach ( $extra as $extraname ) {
+ $field['fields'][$extraname] = array( 'type' =>
'string', 'analyzer' => $extraname );
+ }
+ return $field;
}
private function closeAndCorrect( $callback ) {
--
To view, visit https://gerrit.wikimedia.org/r/75884
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I513b0b1aa35896ba346e48aa2e657f1f6447c625
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/CirrusSearch
Gerrit-Branch: master
Gerrit-Owner: Manybubbles <[email protected]>
Gerrit-Reviewer: Demon <[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