public function executeSearch(PhabricatorSearchQuery $query)
 {
     $spec = array();
     $filter = array();
     if ($query->getQuery()) {
         $spec[] = array('field' => array('field.corpus' => $query->getQuery()));
     }
     $exclude = $query->getParameter('exclude');
     if ($exclude) {
         $filter[] = array('not' => array('ids' => array('values' => array($exclude))));
     }
     $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, 'owner' => PhabricatorSearchRelationship::RELATIONSHIP_OWNER, 'project' => PhabricatorSearchRelationship::RELATIONSHIP_PROJECT, 'repository' => PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY);
     foreach ($rel_mapping as $name => $field) {
         $param = $query->getParameter($name);
         if (is_array($param)) {
             $should = array();
             foreach ($param as $val) {
                 $should[] = array('text' => array("relationship.{$field}.phid" => array('query' => $val, 'type' => 'phrase')));
             }
             // We couldn't solve it by minimum_number_should_match because it can
             // match multiple owners without matching author.
             $spec[] = array('bool' => array('should' => $should));
         } else {
             if ($param) {
                 $filter[] = array('exists' => array('field' => "relationship.{$field}.phid"));
             }
         }
     }
     if ($spec) {
         $spec = array('query' => array('bool' => array('must' => $spec)));
     }
     if ($filter) {
         $filter = array('filter' => array('and' => $filter));
         if ($spec) {
             $spec = array('query' => array('filtered' => $spec + $filter));
         } else {
             $spec = $filter;
         }
     }
     $spec['from'] = (int) $query->getParameter('offset', 0);
     $spec['size'] = (int) $query->getParameter('limit', 25);
     $response = $this->executeRequest($uri, $spec);
     $phids = ipull($response['hits']['hits'], '_id');
     return $phids;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     if ($this->key) {
         $query = id(new PhabricatorSearchQuery())->loadOneWhere('queryKey = %s', $this->key);
         if (!$query) {
             return new Aphront404Response();
         }
     } else {
         $query = new PhabricatorSearchQuery();
         if ($request->isFormPost()) {
             $query_str = $request->getStr('query');
             $pref_jump = PhabricatorUserPreferences::PREFERENCE_SEARCHBAR_JUMP;
             if ($request->getStr('jump') != 'no' && $user && $user->loadPreferences()->getPreference($pref_jump, 1)) {
                 $response = PhabricatorJumpNavHandler::jumpPostResponse($query_str);
             } else {
                 $response = null;
             }
             if ($response) {
                 return $response;
             } else {
                 $query->setQuery($query_str);
                 if ($request->getStr('scope')) {
                     switch ($request->getStr('scope')) {
                         case PhabricatorSearchScope::SCOPE_OPEN_REVISIONS:
                             $query->setParameter('open', 1);
                             $query->setParameter('type', PhabricatorPHIDConstants::PHID_TYPE_DREV);
                             break;
                         case PhabricatorSearchScope::SCOPE_OPEN_TASKS:
                             $query->setParameter('open', 1);
                             $query->setParameter('type', PhabricatorPHIDConstants::PHID_TYPE_TASK);
                             break;
                         case PhabricatorSearchScope::SCOPE_WIKI:
                             $query->setParameter('type', PhabricatorPHIDConstants::PHID_TYPE_WIKI);
                             break;
                         case PhabricatorSearchScope::SCOPE_COMMITS:
                             $query->setParameter('type', PhabricatorPHIDConstants::PHID_TYPE_CMIT);
                             break;
                         default:
                             break;
                     }
                 } else {
                     if (strlen($request->getStr('type'))) {
                         $query->setParameter('type', $request->getStr('type'));
                     }
                     if ($request->getArr('author')) {
                         $query->setParameter('author', $request->getArr('author'));
                     }
                     if ($request->getArr('owner')) {
                         $query->setParameter('owner', $request->getArr('owner'));
                     }
                     if ($request->getInt('open')) {
                         $query->setParameter('open', $request->getInt('open'));
                     }
                     if ($request->getArr('project')) {
                         $query->setParameter('project', $request->getArr('project'));
                     }
                 }
                 $query->save();
                 return id(new AphrontRedirectResponse())->setURI('/search/' . $query->getQueryKey() . '/');
             }
         }
     }
     $options = array('' => 'All Documents') + PhabricatorSearchAbstractDocument::getSupportedTypes();
     $status_options = array(0 => 'Open and Closed Documents', 1 => 'Open Documents');
     $phids = array_merge($query->getParameter('author', array()), $query->getParameter('owner', array()), $query->getParameter('project', array()));
     $handles = $this->loadViewerHandles($phids);
     $author_value = array_select_keys($handles, $query->getParameter('author', array()));
     $author_value = mpull($author_value, 'getFullName', 'getPHID');
     $owner_value = array_select_keys($handles, $query->getParameter('owner', array()));
     $owner_value = mpull($owner_value, 'getFullName', 'getPHID');
     $project_value = array_select_keys($handles, $query->getParameter('project', array()));
     $project_value = mpull($project_value, 'getFullName', 'getPHID');
     $search_form = new AphrontFormView();
     $search_form->setUser($user)->setAction('/search/')->appendChild(phutil_render_tag('input', array('type' => 'hidden', 'name' => 'jump', 'value' => 'no')))->appendChild(id(new AphrontFormTextControl())->setLabel('Search')->setName('query')->setValue($query->getQuery()))->appendChild(id(new AphrontFormSelectControl())->setLabel('Document Type')->setName('type')->setOptions($options)->setValue($query->getParameter('type')))->appendChild(id(new AphrontFormSelectControl())->setLabel('Document Status')->setName('open')->setOptions($status_options)->setValue($query->getParameter('open')))->appendChild(id(new AphrontFormTokenizerControl())->setName('author')->setLabel('Author')->setDatasource('/typeahead/common/users/')->setValue($author_value))->appendChild(id(new AphrontFormTokenizerControl())->setName('owner')->setLabel('Owner')->setDatasource('/typeahead/common/searchowner/')->setValue($owner_value)->setCaption('Tip: search for "Up For Grabs" to find unowned documents.'))->appendChild(id(new AphrontFormTokenizerControl())->setName('project')->setLabel('Project')->setDatasource('/typeahead/common/projects/')->setValue($project_value))->appendChild(id(new AphrontFormSubmitControl())->setValue('Search'));
     $search_panel = new AphrontPanelView();
     $search_panel->setHeader('Search Phabricator');
     $search_panel->appendChild($search_form);
     require_celerity_resource('phabricator-search-results-css');
     if ($query->getID()) {
         $limit = 20;
         $pager = new AphrontPagerView();
         $pager->setURI($request->getRequestURI(), 'page');
         $pager->setPageSize($limit);
         $pager->setOffset($request->getInt('page'));
         $query->setParameter('limit', $limit + 1);
         $query->setParameter('offset', $pager->getOffset());
         $engine = PhabricatorSearchEngineSelector::newSelector()->newEngine();
         $results = $engine->executeSearch($query);
         $results = $pager->sliceResults($results);
         if (!$request->getInt('page')) {
             $jump = PhabricatorPHID::fromObjectName($query->getQuery());
             if ($jump) {
                 array_unshift($results, $jump);
             }
         }
         if ($results) {
             $loader = new PhabricatorObjectHandleData($results);
             $handles = $loader->loadHandles();
             $objects = $loader->loadObjects();
             $results = array();
             foreach ($handles as $phid => $handle) {
                 $view = new PhabricatorSearchResultView();
                 $view->setHandle($handle);
                 $view->setQuery($query);
                 $view->setObject(idx($objects, $phid));
                 $results[] = $view->render();
             }
             $results = '<div class="phabricator-search-result-list">' . implode("\n", $results) . '<div class="search-results-pager">' . $pager->render() . '</div>' . '</div>';
         } else {
             $results = '<div class="phabricator-search-result-list">' . '<p class="phabricator-search-no-results">No search results.</p>' . '</div>';
         }
     } else {
         $results = null;
     }
     return $this->buildStandardPageResponse(array($search_panel, $results), array('title' => 'Search Results'));
 }
 public static function loadTasks(PhabricatorSearchQuery $search_query)
 {
     $any_project = false;
     $search_text = $search_query->getParameter('fullTextSearch');
     $user_phids = $search_query->getParameter('userPHIDs', array());
     $project_phids = $search_query->getParameter('projectPHIDs', array());
     $task_ids = $search_query->getParameter('taskIDs', array());
     $xproject_phids = $search_query->getParameter('excludeProjectPHIDs', array());
     $owner_phids = $search_query->getParameter('ownerPHIDs', array());
     $author_phids = $search_query->getParameter('authorPHIDs', array());
     $low_priority = $search_query->getParameter('lowPriority');
     $low_priority = nonempty($low_priority, ManiphestTaskPriority::getLowestPriority());
     $high_priority = $search_query->getParameter('highPriority');
     $high_priority = nonempty($high_priority, ManiphestTaskPriority::getHighestPriority());
     $query = new ManiphestTaskQuery();
     $query->withProjects($project_phids);
     $query->withTaskIDs($task_ids);
     if ($xproject_phids) {
         $query->withoutProjects($xproject_phids);
     }
     if ($owner_phids) {
         $query->withOwners($owner_phids);
     }
     if ($author_phids) {
         $query->withAuthors($author_phids);
     }
     $status = $search_query->getParameter('status', 'all');
     if (!empty($status['open']) && !empty($status['closed'])) {
         $query->withStatus(ManiphestTaskQuery::STATUS_ANY);
     } else {
         if (!empty($status['open'])) {
             $query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
         } else {
             $query->withStatus(ManiphestTaskQuery::STATUS_CLOSED);
         }
     }
     switch ($search_query->getParameter('view')) {
         case 'action':
             $query->withOwners($user_phids);
             break;
         case 'created':
             $query->withAuthors($user_phids);
             break;
         case 'subscribed':
             $query->withSubscribers($user_phids);
             break;
         case 'triage':
             $query->withOwners($user_phids);
             $query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
             break;
         case 'alltriage':
             $query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
             break;
         case 'all':
             break;
         case 'projecttriage':
             $query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
             $any_project = true;
             break;
         case 'projectall':
             $any_project = true;
             break;
         case 'custom':
             $query->withPrioritiesBetween($low_priority, $high_priority);
             break;
     }
     $query->withAnyProject($any_project);
     $query->withFullTextSearch($search_text);
     $order_map = array('priority' => ManiphestTaskQuery::ORDER_PRIORITY, 'created' => ManiphestTaskQuery::ORDER_CREATED, 'title' => ManiphestTaskQuery::ORDER_TITLE);
     $query->setOrderBy(idx($order_map, $search_query->getParameter('order'), ManiphestTaskQuery::ORDER_MODIFIED));
     $group_map = array('priority' => ManiphestTaskQuery::GROUP_PRIORITY, 'owner' => ManiphestTaskQuery::GROUP_OWNER, 'status' => ManiphestTaskQuery::GROUP_STATUS, 'project' => ManiphestTaskQuery::GROUP_PROJECT);
     $query->setGroupBy(idx($group_map, $search_query->getParameter('group'), ManiphestTaskQuery::GROUP_NONE));
     $query->setCalculateRows(true);
     $query->setLimit($search_query->getParameter('limit'));
     $query->setOffset($search_query->getParameter('offset'));
     $data = $query->execute();
     $total_row_count = $query->getRowCount();
     $project_group_phids = array();
     if ($search_query->getParameter('group') == 'project') {
         foreach ($data as $task) {
             foreach ($task->getProjectPHIDs() as $phid) {
                 $project_group_phids[] = $phid;
             }
         }
     }
     $handle_phids = mpull($data, 'getOwnerPHID');
     $handle_phids = array_merge($handle_phids, $project_phids, $user_phids, $xproject_phids, $owner_phids, $author_phids, $project_group_phids, array_mergev(mpull($data, 'getProjectPHIDs')));
     $handles = id(new PhabricatorObjectHandleData($handle_phids))->loadHandles();
     switch ($search_query->getParameter('group')) {
         case 'priority':
             $data = mgroup($data, 'getPriority');
             // If we have invalid priorities, they'll all map to "???". Merge
             // arrays to prevent them from overwriting each other.
             $out = array();
             foreach ($data as $pri => $tasks) {
                 $out[ManiphestTaskPriority::getTaskPriorityName($pri)][] = $tasks;
             }
             foreach ($out as $pri => $tasks) {
                 $out[$pri] = array_mergev($tasks);
             }
             $data = $out;
             break;
         case 'status':
             $data = mgroup($data, 'getStatus');
             $out = array();
             foreach ($data as $status => $tasks) {
                 $out[ManiphestTaskStatus::getTaskStatusFullName($status)] = $tasks;
             }
             $data = $out;
             break;
         case 'owner':
             $data = mgroup($data, 'getOwnerPHID');
             $out = array();
             foreach ($data as $phid => $tasks) {
                 if ($phid) {
                     $out[$handles[$phid]->getFullName()] = $tasks;
                 } else {
                     $out['Unassigned'] = $tasks;
                 }
             }
             $data = $out;
             ksort($data);
             // Move "Unassigned" to the top of the list.
             if (isset($data['Unassigned'])) {
                 $data = array('Unassigned' => $out['Unassigned']) + $out;
             }
             break;
         case 'project':
             $grouped = array();
             foreach ($query->getGroupByProjectResults() as $project => $tasks) {
                 foreach ($tasks as $task) {
                     $group = $project ? $handles[$project]->getName() : 'No Project';
                     $grouped[$group][$task->getID()] = $task;
                 }
             }
             $data = $grouped;
             ksort($data);
             // Move "No Project" to the end of the list.
             if (isset($data['No Project'])) {
                 $noproject = $data['No Project'];
                 unset($data['No Project']);
                 $data += array('No Project' => $noproject);
             }
             break;
         default:
             $data = array('Tasks' => $data);
             break;
     }
     return array($data, $handles, $total_row_count);
 }
 protected function joinRelationship(AphrontDatabaseConnection $conn, PhabricatorSearchQuery $query, $field, $type)
 {
     $phids = $query->getParameter($field, array());
     if (!$phids) {
         return null;
     }
     $is_existence = false;
     switch ($type) {
         case PhabricatorSearchRelationship::RELATIONSHIP_OPEN:
             $is_existence = true;
             break;
     }
     $sql = qsprintf($conn, '%T AS %C ON %C.phid = document.phid AND %C.relation = %s', id(new PhabricatorSearchDocumentRelationship())->getTableName(), $field, $field, $field, $type);
     if (!$is_existence) {
         $sql .= qsprintf($conn, ' AND %C.relatedPHID in (%Ls)', $field, $phids);
     }
     return $sql;
 }
 public function executeSearch(PhabricatorSearchQuery $query)
 {
     $where = array();
     $join = array();
     $order = 'ORDER BY documentCreated DESC';
     $dao_doc = new PhabricatorSearchDocument();
     $dao_field = new PhabricatorSearchDocumentField();
     $t_doc = $dao_doc->getTableName();
     $t_field = $dao_field->getTableName();
     $conn_r = $dao_doc->establishConnection('r');
     $q = $query->getQuery();
     if (strlen($q)) {
         $join[] = qsprintf($conn_r, "{$t_field} field ON field.phid = document.phid");
         $where[] = qsprintf($conn_r, 'MATCH(corpus) AGAINST (%s IN BOOLEAN MODE)', $q);
         // When searching for a string, promote user listings above other
         // listings.
         $order = qsprintf($conn_r, 'ORDER BY
       IF(documentType = %s, 0, 1) ASC,
       MAX(MATCH(corpus) AGAINST (%s)) DESC', 'USER', $q);
         $field = $query->getParameter('field');
         if ($field) {
             $where[] = qsprintf($conn_r, 'field.field = %s', $field);
         }
     }
     $exclude = $query->getParameter('exclude');
     if ($exclude) {
         $where[] = qsprintf($conn_r, 'document.phid != %s', $exclude);
     }
     if ($query->getParameter('type')) {
         if (strlen($q)) {
             // TODO: verify that this column actually does something useful in query
             // plans once we have nontrivial amounts of data.
             $where[] = qsprintf($conn_r, 'field.phidType = %s', $query->getParameter('type'));
         }
         $where[] = qsprintf($conn_r, 'document.documentType = %s', $query->getParameter('type'));
     }
     $join[] = $this->joinRelationship($conn_r, $query, 'author', PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR);
     $join[] = $this->joinRelationship($conn_r, $query, 'open', PhabricatorSearchRelationship::RELATIONSHIP_OPEN);
     $join[] = $this->joinRelationship($conn_r, $query, 'owner', PhabricatorSearchRelationship::RELATIONSHIP_OWNER);
     $join[] = $this->joinRelationship($conn_r, $query, 'project', PhabricatorSearchRelationship::RELATIONSHIP_PROJECT);
     $join[] = $this->joinRelationship($conn_r, $query, 'repository', PhabricatorSearchRelationship::RELATIONSHIP_REPOSITORY);
     /*
         $join[] = $this->joinRelationship(
           $conn_r,
           $query,
           'reviewer',
           AdjutantRelationship::RELATIONSHIP_REVIEWER);
         $join[] = $this->joinRelationship(
           $conn_r,
           $query,
           'subscriber',
           AdjutantRelationship::RELATIONSHIP_SUBSCRIBER);
         $join[] = $this->joinRelationship(
           $conn_r,
           $query,
           'repository',
           AdjutantRelationship::RELATIONSHIP_REPOSITORY);
     */
     $join = array_filter($join);
     foreach ($join as $key => $clause) {
         $join[$key] = ' JOIN ' . $clause;
     }
     $join = implode(' ', $join);
     if ($where) {
         $where = 'WHERE ' . implode(' AND ', $where);
     } else {
         $where = '';
     }
     $offset = (int) $query->getParameter('offset', 0);
     $limit = (int) $query->getParameter('limit', 25);
     $hits = queryfx_all($conn_r, 'SELECT
       document.phid,
       document.documentType,
       document.documentTitle,
       document.documentCreated
     FROM %T document
       %Q
       %Q
     GROUP BY document.phid
       %Q
     LIMIT %d, %d', $t_doc, $join, $where, $order, $offset, $limit);
     return $hits;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     if ($this->id) {
         $query = id(new PhabricatorSearchQuery())->load($this->id);
         if (!$query) {
             return new Aphront404Response();
         }
     } else {
         $query = new PhabricatorSearchQuery();
         if ($request->isFormPost()) {
             $query->setQuery($request->getStr('query'));
             if (strlen($request->getStr('type'))) {
                 $query->setParameter('type', $request->getStr('type'));
             }
             if ($request->getArr('author')) {
                 $query->setParameter('author', $request->getArr('author'));
             }
             if ($request->getArr('owner')) {
                 $query->setParameter('owner', $request->getArr('owner'));
             }
             if ($request->getInt('open')) {
                 $query->setParameter('open', $request->getInt('open'));
             }
             if ($request->getArr('project')) {
                 $query->setParameter('project', $request->getArr('project'));
             }
             $query->save();
             return id(new AphrontRedirectResponse())->setURI('/search/' . $query->getID() . '/');
         }
     }
     $more = PhabricatorEnv::getEnvConfig('search.more-document-types', array());
     $options = array('' => 'All Documents', PhabricatorPHIDConstants::PHID_TYPE_DREV => 'Differential Revisions', PhabricatorPHIDConstants::PHID_TYPE_CMIT => 'Repository Commits', PhabricatorPHIDConstants::PHID_TYPE_TASK => 'Maniphest Tasks', PhabricatorPHIDConstants::PHID_TYPE_WIKI => 'Phriction Documents', PhabricatorPHIDConstants::PHID_TYPE_USER => 'Phabricator Users') + $more;
     $status_options = array(0 => 'Open and Closed Documents', 1 => 'Open Documents');
     $phids = array_merge($query->getParameter('author', array()), $query->getParameter('owner', array()), $query->getParameter('project', array()));
     $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
     $author_value = array_select_keys($handles, $query->getParameter('author', array()));
     $author_value = mpull($author_value, 'getFullName', 'getPHID');
     $owner_value = array_select_keys($handles, $query->getParameter('owner', array()));
     $owner_value = mpull($owner_value, 'getFullName', 'getPHID');
     $project_value = array_select_keys($handles, $query->getParameter('project', array()));
     $project_value = mpull($project_value, 'getFullName', 'getPHID');
     $search_form = new AphrontFormView();
     $search_form->setUser($user)->setAction('/search/')->appendChild(id(new AphrontFormTextControl())->setLabel('Search')->setName('query')->setValue($query->getQuery()))->appendChild(id(new AphrontFormSelectControl())->setLabel('Document Type')->setName('type')->setOptions($options)->setValue($query->getParameter('type')))->appendChild(id(new AphrontFormSelectControl())->setLabel('Document Status')->setName('open')->setOptions($status_options)->setValue($query->getParameter('open')))->appendChild(id(new AphrontFormTokenizerControl())->setName('author')->setLabel('Author')->setDatasource('/typeahead/common/users/')->setValue($author_value))->appendChild(id(new AphrontFormTokenizerControl())->setName('owner')->setLabel('Owner')->setDatasource('/typeahead/common/searchowner/')->setValue($owner_value)->setCaption('Tip: search for "Up For Grabs" to find unowned documents.'))->appendChild(id(new AphrontFormTokenizerControl())->setName('project')->setLabel('Project')->setDatasource('/typeahead/common/projects/')->setValue($project_value))->appendChild(id(new AphrontFormSubmitControl())->setValue('Search'));
     $search_panel = new AphrontPanelView();
     $search_panel->setHeader('Search Phabricator');
     $search_panel->appendChild($search_form);
     require_celerity_resource('phabricator-search-results-css');
     if ($query->getID()) {
         $limit = 20;
         $pager = new AphrontPagerView();
         $pager->setURI($request->getRequestURI(), 'page');
         $pager->setPageSize($limit);
         $pager->setOffset($request->getInt('page'));
         $query->setParameter('limit', $limit + 1);
         $query->setParameter('offset', $pager->getOffset());
         $executor = new PhabricatorSearchMySQLExecutor();
         $results = $executor->executeSearch($query);
         $results = ipull($results, 'phid');
         $results = $pager->sliceResults($results);
         if ($results) {
             $loader = new PhabricatorObjectHandleData($results);
             $handles = $loader->loadHandles();
             $objects = $loader->loadObjects();
             $results = array();
             foreach ($handles as $phid => $handle) {
                 $view = new PhabricatorSearchResultView();
                 $view->setHandle($handle);
                 $view->setQuery($query);
                 $view->setObject($objects[$phid]);
                 $results[] = $view->render();
             }
             $results = '<div class="phabricator-search-result-list">' . implode("\n", $results) . '<div class="search-results-pager">' . $pager->render() . '</div>' . '</div>';
         } else {
             $results = '<div class="phabricator-search-result-list">' . '<p class="phabricator-search-no-results">No search results.</p>' . '</div>';
         }
     } else {
         $results = null;
     }
     return $this->buildStandardPageResponse(array($search_panel, $results), array('title' => 'Results: what'));
 }
 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;
 }