diff --git a/src/applications/search/engine/PhabricatorSearchEngineElastic.php b/src/applications/search/engine/PhabricatorSearchEngineElastic.php index 8a4f23cc9c..be0cf71653 100644 --- a/src/applications/search/engine/PhabricatorSearchEngineElastic.php +++ b/src/applications/search/engine/PhabricatorSearchEngineElastic.php @@ -104,8 +104,7 @@ final class PhabricatorSearchEngineElastic extends PhabricatorSearchEngine { return $doc; } - public function executeSearch(PhabricatorSearchQuery $query) { - + private function buildSpec(PhabricatorSearchQuery $query) { $spec = array(); $filter = array(); @@ -128,17 +127,6 @@ final class PhabricatorSearchEngineElastic extends PhabricatorSearchEngine { ); } - $type = $query->getParameter('type'); - if ($type) { - $uri = "/phabricator/{$type}/_search"; - } else { - // Don't use '/phabricator/_search' for the case that there is something - // else in the index (for example if 'phabricator' is only an alias to - // some bigger index). - $types = PhabricatorSearchAbstractDocument::getSupportedTypes(); - $uri = '/phabricator/' . implode(',', array_keys($types)) . '/_search'; - } - $rel_mapping = array( 'author' => PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, 'open' => PhabricatorSearchRelationship::RELATIONSHIP_OPEN, @@ -191,7 +179,35 @@ final class PhabricatorSearchEngineElastic extends PhabricatorSearchEngine { $spec['from'] = (int)$query->getParameter('offset', 0); $spec['size'] = (int)$query->getParameter('limit', 25); - $response = $this->executeRequest($uri, $spec); + + return $spec; + } + + public function executeSearch(PhabricatorSearchQuery $query) { + $type = $query->getParameter('type'); + if ($type) { + $uri = "/phabricator/{$type}/_search"; + } else { + // Don't use '/phabricator/_search' for the case that there is something + // else in the index (for example if 'phabricator' is only an alias to + // some bigger index). + $types = PhabricatorSearchAbstractDocument::getSupportedTypes(); + $uri = '/phabricator/' . implode(',', array_keys($types)) . '/_search'; + } + + try { + $response = $this->executeRequest($uri, $this->buildSpec($query)); + } catch (HTTPFutureResponseStatusHTTP $ex) { + // elasticsearch probably uses Lucene query syntax: + // http://lucene.apache.org/core/3_6_1/queryparsersyntax.html + // Try literal search if operator search fails. + if (!$query->getQuery()) { + throw $ex; + } + $query = clone $query; + $query->setQuery(addcslashes($query->getQuery(), '+-&|!(){}[]^"~*?:\\')); + $response = $this->executeRequest($uri, $this->buildSpec($query)); + } $phids = ipull($response['hits']['hits'], '_id'); return $phids;