Page MenuHomePhabricator

D18539.id44519.diff
No OneTemporary

D18539.id44519.diff

diff --git a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
--- a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
+++ b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
@@ -251,6 +251,7 @@
}
$select[] = $this->buildEdgeLogicSelectClause($conn);
+ $select[] = $this->buildFerretSelectClause($conn);
return $select;
}
@@ -769,6 +770,13 @@
}
}
+ if ($this->supportsFerretEngine()) {
+ $orders['relevance'] = array(
+ 'vector' => array('rank', 'id'),
+ 'name' => pht('Relevence'),
+ );
+ }
+
return $orders;
}
@@ -961,6 +969,14 @@
}
}
+ if ($this->supportsFerretEngine()) {
+ $columns['rank'] = array(
+ 'table' => null,
+ 'column' => '_ft_rank',
+ 'type' => 'int',
+ );
+ }
+
$cache->setKey($cache_key, $columns);
return $columns;
@@ -1385,10 +1401,23 @@
/* -( Ferret )------------------------------------------------------------- */
+ public function supportsFerretEngine() {
+ $object = $this->newResultObject();
+ return ($object instanceof PhabricatorFerretInterface);
+ }
+
+
public function withFerretConstraint(
PhabricatorFerretEngine $engine,
array $fulltext_tokens) {
+ if (!$this->supportsFerretEngine()) {
+ throw new Exception(
+ pht(
+ 'Query ("%s") does not support the Ferret fulltext engine.',
+ get_class($this)));
+ }
+
if ($this->ferretEngine) {
throw new Exception(
pht(
@@ -1416,7 +1445,7 @@
$raw_field = $engine->getFieldForFunction($function);
if (!isset($table_map[$function])) {
- $alias = 'ftfield'.$idx++;
+ $alias = 'ftfield_'.$idx++;
$table_map[$function] = array(
'alias' => $alias,
'key' => $raw_field,
@@ -1426,11 +1455,101 @@
$current_function = $function;
}
+ // Join the title field separately so we can rank results.
+ $table_map['rank'] = array(
+ 'alias' => 'ft_rank',
+ 'key' => PhabricatorSearchDocumentFieldType::FIELD_TITLE,
+ );
+
$this->ferretTables = $table_map;
return $this;
}
+ protected function buildFerretSelectClause(AphrontDatabaseConnection $conn) {
+ $select = array();
+
+ if (!$this->supportsFerretEngine()) {
+ return $select;
+ }
+
+ if (!$this->ferretEngine) {
+ $select[] = '0 _ft_rank';
+ return $select;
+ }
+
+ $engine = $this->ferretEngine;
+ $stemmer = $engine->newStemmer();
+
+ $op_sub = PhutilSearchQueryCompiler::OPERATOR_SUBSTRING;
+ $op_not = PhutilSearchQueryCompiler::OPERATOR_NOT;
+ $table_alias = 'ft_rank';
+
+ $parts = array();
+ foreach ($this->ferretTokens as $fulltext_token) {
+ $raw_token = $fulltext_token->getToken();
+ $value = $raw_token->getValue();
+
+ if ($raw_token->getOperator() == $op_not) {
+ // Ignore "not" terms when ranking, since they aren't useful.
+ continue;
+ }
+
+ if ($raw_token->getOperator() == $op_sub) {
+ $is_substring = true;
+ } else {
+ $is_substring = false;
+ }
+
+ if ($is_substring) {
+ $parts[] = qsprintf(
+ $conn,
+ 'IF(%T.rawCorpus LIKE %~, 2, 0)',
+ $table_alias,
+ $value);
+ continue;
+ }
+
+ if ($raw_token->isQuoted()) {
+ $is_quoted = true;
+ $is_stemmed = false;
+ } else {
+ $is_quoted = false;
+ $is_stemmed = true;
+ }
+
+ $term_constraints = array();
+
+ $term_value = $engine->newTermsCorpus($value);
+
+ $parts[] = qsprintf(
+ $conn,
+ 'IF(%T.termCorpus LIKE %~, 2, 0)',
+ $table_alias,
+ $term_value);
+
+ if ($is_stemmed) {
+ $stem_value = $stemmer->stemToken($value);
+ $stem_value = $engine->newTermsCorpus($stem_value);
+
+ $parts[] = qsprintf(
+ $conn,
+ 'IF(%T.normalCorpus LIKE %~, 1, 0)',
+ $table_alias,
+ $stem_value);
+ }
+
+ $parts[] = '0';
+ }
+
+ $select[] = qsprintf(
+ $conn,
+ '%Q _ft_rank',
+ implode(' + ', $parts));
+
+ return $select;
+ }
+
protected function buildFerretJoinClause(AphrontDatabaseConnection $conn) {
if (!$this->ferretEngine) {
return array();

File Metadata

Mime Type
text/plain
Expires
Oct 15 2024, 5:46 PM (4 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6713751
Default Alt Text
D18539.id44519.diff (4 KB)

Event Timeline