/** * Initiate the FTS indexer. Once initiated, all work will be done by the FTS consumers which will be invoked * by the job queue system. * * @param array $modules Modules to index * @param bool $deleteExistingData Remove existing index * @param bool $runNow Run indexing jobs immediately instead of placing them in job queue * @return SugarSearchEngineFullIndexer */ public function initiateFTSIndexer(array $modules = array(), $deleteExistingData = true, $runNow = false) { $startTime = microtime(true); $GLOBALS['log']->info("Populating Full System Index Queue at {$startTime}"); if (!$this->SSEngine instanceof SugarSearchEngineAbstractBase) { $GLOBALS['log']->info("No FTS engine enabled, not doing anything"); return false; } $allModules = !empty($modules) ? $modules : array_keys(SugarSearchEngineMetadataHelper::retrieveFtsEnabledFieldsForAllModules()); // Create the index on the server side $this->SSEngine->createIndex($deleteExistingData, $allModules); // Clear the existing queue $this->clearFTSIndexQueue($allModules); // clear flag $admin = Administration::getSettings(); if (!empty($admin->settings['info_fts_index_done'])) { $admin->saveSetting('info', 'fts_index_done', 0); } $totalCount = 0; foreach ($allModules as $module) { $totalCount += $this->populateIndexQueueForModule($module, $runNow); } $totalTime = number_format(round(microtime(true) - $startTime, 2), 2); $this->results['totalTime'] = $totalTime; $GLOBALS['log']->info("Total time to populate full system index queue: {$totalTime} (s)"); $avgRecs = $totalCount != 0 && $totalTime != 0 ? number_format(round($totalCount / $totalTime, 2), 2) : 0; $GLOBALS['log']->info("Total number of modules queued: {$totalCount} , modules per sec. {$avgRecs}"); return $this; }
/** * * This function creates a full mapping for all modules. * index must exist before calling this function. * */ public function setFullMapping() { $allModules = SugarSearchEngineMetadataHelper::retrieveFtsEnabledFieldsForAllModules(); // if the index already exists, is there a way to create mapping for multiple modules at once? // for now, create one mapping for a module at a time foreach ($allModules as $name => $module) { $this->setFieldMapping($name, $module); } }
/** * This function returns an array of fields that can be passed to search engine. * @param Array $options * @param boolean $prefixed Add module name prefix (i.e. Contacts.first_name) * @return Array array of fields */ protected function getSearchFields($options, $prefixed = true) { $fields = array(); // determine list of modules/fields $allFieldDefs = array(); if (!empty($options['moduleFilter'])) { foreach ($options['moduleFilter'] as $module) { $allFieldDefs[$module] = SugarSearchEngineMetadataHelper::retrieveFtsEnabledFieldsPerModule($module); } } else { $allFieldDefs = SugarSearchEngineMetadataHelper::retrieveFtsEnabledFieldsForAllModules(); } // build list of fields with optional boost values (i.e. Accouns.name^3) foreach ($allFieldDefs as $module => $fieldDefs) { foreach ($fieldDefs as $fieldName => $fieldDef) { // skip non-supported field types $ftsType = $this->mapper->getFtsTypeFromDef($fieldDef); if (!$ftsType || in_array($ftsType['type'], $this->ignoreSearchTypes)) { $this->logger->debug("Elastic: Ignoring unsupported type in query for {$module}/{$fieldName}"); continue; } // base field name if ($prefixed) { $fieldName = $module . '.' . $fieldName; } // To enable a field for user search we require a boost value. There may be other fields // we index into Elastic but which should not be user searchable. We use the boost value // being set or not to distinguish between both scenarios. For example for extended facets // and related fields we can store additional fields or non analyzed data. While we need // those fields being indexed, we do not want the user to be able to hit those when // performing a search. if (empty($fieldDef['full_text_search']['boost'])) { $this->logger->debug("Elastic: skipping {$module}/{$fieldName} for search field (no boost set)"); continue; } else { if (!empty($options['addSearchBoosts'])) { $fieldName .= '^' . $fieldDef['full_text_search']['boost']; } $fields[] = $fieldName; } } } return $fields; }