3 final class PhabricatorFerretFulltextStorageEngine
4 extends PhabricatorFulltextStorageEngine
{
6 private $fulltextTokens = array();
9 public function getEngineIdentifier() {
13 public function getHostType() {
14 return new PhabricatorMySQLSearchHost($this);
17 public function reindexAbstractDocument(
18 PhabricatorSearchAbstractDocument
$doc) {
20 // NOTE: The Ferret engine indexes are rebuilt by an extension rather than
21 // by the main fulltext engine, and are always built regardless of
27 public function executeSearch(PhabricatorSavedQuery
$query) {
28 $all_objects = id(new PhutilClassMapQuery())
29 ->setAncestorClass('PhabricatorFerretInterface')
33 foreach ($all_objects as $object) {
34 $phid_type = phid_get_type($object->generatePHID());
36 $type_map[$phid_type] = array(
38 'engine' => $object->newFerretEngine(),
42 $types = $query->getParameter('types');
44 $type_map = array_select_keys($type_map, $types);
47 $offset = (int)$query->getParameter('offset', 0);
48 $limit = (int)$query->getParameter('limit', 25);
50 // NOTE: For now, it's okay to query with the omnipotent viewer here
51 // because we're just returning PHIDs which we'll filter later.
52 $viewer = PhabricatorUser
::getOmnipotentUser();
54 $type_results = array();
56 foreach ($type_map as $type => $spec) {
57 $engine = $spec['engine'];
58 $object = $spec['object'];
60 $local_query = new PhabricatorSavedQuery();
61 $local_query->setParameter('query', $query->getParameter('query'));
63 $project_phids = $query->getParameter('projectPHIDs');
65 $local_query->setParameter('projectPHIDs', $project_phids);
68 $subscriber_phids = $query->getParameter('subscriberPHIDs');
69 if ($subscriber_phids) {
70 $local_query->setParameter('subscriberPHIDs', $subscriber_phids);
73 $search_engine = $engine->newSearchEngine()
76 $engine_query = $search_engine->buildQueryFromSavedQuery($local_query)
80 ->withFerretQuery($engine, $query)
81 ->setOrder('relevance')
82 ->setLimit($offset +
$limit);
84 $results = $engine_query->execute();
85 $results = mpull($results, null, 'getPHID');
86 $type_results[$type] = $results;
88 $metadata +
= $engine_query->getFerretMetadata();
90 if (!$this->fulltextTokens
) {
91 $this->fulltextTokens
= $engine_query->getFerretTokens();
96 foreach ($type_results as $type => $results) {
100 // Currently, the list is grouped by object type. For example, all the
101 // tasks might be first, then all the revisions, and so on. In each group,
102 // the results are ordered properly.
104 // Reorder the results so that the highest-ranking results come first,
105 // no matter which object types they belong to.
107 $metadata = msortv($metadata, 'getRelevanceSortVector');
108 $list = array_select_keys($list, array_keys($metadata)) +
$list;
110 $result_slice = array_slice($list, $offset, $limit, true);
111 return array_keys($result_slice);
114 public function indexExists() {
118 public function getIndexStats() {
122 public function getFulltextTokens() {
123 return $this->fulltextTokens
;