From cb4add31164917bd4c56e97fd17d03cd9cb7a27b Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 18 Jul 2019 10:19:03 -0700 Subject: [PATCH] In Ferret, allow documents with no title to match query terms by using LEFT JOIN on the "title" ranking field Summary: Fixes T13345. See D20650. Currently, `PhabricatorCursorPagedPolicyAwareQuery` does a JOIN against the "title" field so it can apply additional ranking/ordering conditions to the query. This means that documents with no title (which don't have this field) are always excluded from the result set. We'd prefer to include them, just not give them any bonus ranking/relevance boost. Use a LEFT JOIN so they get included. Test Plan: - Applied D20650 (diff 1), made it use raw `getTitle()` as the document title, indexed a paste with no title. - Searched for a term in the paste body. - Before change: no results. - After change: found result. {F6601159} Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13345 Differential Revision: https://secure.phabricator.com/D20660 --- .../PhabricatorCursorPagedPolicyAwareQuery.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php index 978de0fcf8..a8300c9da2 100644 --- a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php +++ b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php @@ -1825,6 +1825,11 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery $table_map['rank'] = array( 'alias' => 'ft_rank', 'key' => PhabricatorSearchDocumentFieldType::FIELD_TITLE, + + // See T13345. Not every document has a title, so we want to LEFT JOIN + // this table to avoid excluding documents with no title that match + // the query in other fields. + 'optional' => true, ); $this->ferretTables = $table_map; @@ -2103,10 +2108,17 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery foreach ($this->ferretTables as $table) { $alias = $table['alias']; + if (empty($table['optional'])) { + $join_type = qsprintf($conn, 'JOIN'); + } else { + $join_type = qsprintf($conn, 'LEFT JOIN'); + } + $joins[] = qsprintf( $conn, - 'JOIN %T %T ON ft_doc.id = %T.documentID + '%Q %T %T ON ft_doc.id = %T.documentID AND %T.fieldKey = %s', + $join_type, $field_table, $alias, $alias,