<?php

ini_set("display_errors", true);
require_once __DIR__ . '/../vendor/autoload.php';
$client = new \Elastica\Client();
$search = new Elastica\Search($client);
$search->addIndex('comicbook')->addType('superhero');
$query = new Elastica\Query();
$query->setSize(10)->setSort(['name' => 'asc']);
$searchText = "Kent";
$stringQuery = new Elastica\Query\QueryString($searchText);
$query->setQuery($stringQuery);
$query->setHighlight(array('pre_tags' => array('<strong>'), 'post_tags' => array('</strong>'), 'fields' => array('name' => array('force_source' => true), 'summary' => array('force_source' => true))));
$search->setQuery($query);
$resultSet = $search->search();
echo 'Search "' . $searchText . '"<br />' . PHP_EOL;
echo 'Founded ' . $resultSet->getTotalHits() . ' records in ' . $resultSet->getTotalTime() . 'ms<br /><br />' . PHP_EOL;
foreach ($resultSet as $result) {
    $data = $result->getData();
    foreach ($result->getHighlights() as $key => $value) {
        $data[$key] = join(PHP_EOL, $value);
    }
    echo $data['name'] . ' - ' . $data['summary'] . "<br /><br />" . PHP_EOL;
}
 /**
  * @param bool $count whether the count or results \Elastica\ResultSet should be returned
  * @return \Elastica\ResultSet
  */
 public function getResultSet($count = false)
 {
     $cnt = (int) $count;
     $search = new Elastica\Search($this->model->getElasticDbConnection());
     $search->addIndex($this->model->getElasticIndex())->addType($this->model->getElasticType())->setQuery($this->getQuery($count));
     $this->resultSet[$cnt] = $search->search();
     return $this->resultSet[$cnt];
 }
Example #3
0
 /**
  * Creates new record of the given module and returns its formatted representation
  *
  * @param ServiceBase $api
  * @param array       $args API arguments
  *
  * @return array Formatted representation of the bean
  * @throws SugarApiExceptionInvalidParameter
  * @throws SugarApiExceptionMissingParameter
  * @throws SugarApiExceptionNotAuthorized
  */
 public function findNear(ServiceBase $api, array $args)
 {
     if (empty($args['location']) || empty($args['lat_long'])) {
         throw new SugarApiExceptionMissingParameter("Missing location");
     }
     $modules = !empty($args['module']) ? array($args['module']) : $this->getValidModules();
     // Load global search engine
     $engine = $this->getEngine();
     $iName = $engine->getReadIndexName($modules);
     $client = $engine->getClient();
     $index = $client->getIndex($iName);
     $query = new Elastica\Query\MatchAll();
     $search = new Elastica\Search($client);
     $search->addIndex($index);
     foreach ($modules as $module) {
         $search->addType($module);
     }
     if (!empty($args['distance'])) {
         $filter = new Elastica\Filter\GeoDistance('lat_long_c', $args['location'], $args['distance']);
         $query = new Elastica\Query\Filtered($query, $filter);
     }
     //Add sort
     $query = Elastica\Query::create($query);
     $query->addSort(array('_geo_distance' => array("lat_long_c" => $args['location'], "order" => "asc", "unit" => "mi")));
     $results = $search->search($query)->getResults();
     $ret = array();
     foreach ($results as $result) {
         $dist = $result->getParam("sort");
         $module = $result->getType();
         $bean = $this->formatBeanFromResult($api, $args, $result, BeanFactory::getBean($module));
         $bean['_distance'] = $dist[0];
         $bean['_distance_unit'] = 'mi';
         $ret[] = $bean;
     }
     return $ret;
 }
 public function applyAction($actionName, $httpVars, $fileVars)
 {
     $messages = ConfService::getMessages();
     $repoId = $this->accessDriver->repository->getId();
     if ($actionName == "search") {
         // TMP
         if (strpos($httpVars["query"], "keyword:") === 0) {
             $parts = explode(":", $httpVars["query"]);
             $this->applyAction("search_by_keyword", array("field" => $parts[1]), array());
             return;
         }
         try {
             $this->loadIndex($repoId, false);
         } catch (Exception $ex) {
             $this->applyAction("index", array(), array());
             throw new Exception($messages["index.lucene.7"]);
         }
         $textQuery = $httpVars["query"];
         if ($this->getFilteredOption("AUTO_WILDCARD") === true && strlen($textQuery) > 0 && ctype_alnum($textQuery)) {
             if ($textQuery[0] == '"' && $textQuery[strlen($textQuery) - 1] == '"') {
                 $textQuery = substr($textQuery, 1, -1);
             } else {
                 if ($textQuery[strlen($textQuery) - 1] != "*") {
                     $textQuery .= "*";
                 }
             }
         }
         $this->currentIndex->open();
         $fieldQuery = new Elastica\Query\QueryString();
         $fieldQuery->setAllowLeadingWildcard(false);
         $fieldQuery->setFuzzyMinSim(0.8);
         if ($textQuery == "*") {
             $fields = array("ajxp_node");
             $fieldQuery->setQuery("yes");
             $fieldQuery->setFields($fields);
         } else {
             if (strpos($textQuery, ":") !== false) {
                 // USE LUCENE DSL DIRECTLY (key1:value1 AND key2:value2...)
                 $textQuery = str_replace("ajxp_meta_ajxp_document_content:", "body:", $textQuery);
                 $textQuery = $this->filterSearchRangesKeywords($textQuery);
                 $fieldQuery->setQuery($textQuery);
             } else {
                 $fields = array("basename", "ajxp_meta_*", "node_*", "body");
                 $fieldQuery->setQuery($textQuery);
                 $fieldQuery->setFields($fields);
             }
         }
         /*
         TODO : READAPT QUERY WITH EACH FIELD
         if ((isSet($this->metaFields) || $this->indexContent) && isSet($httpVars["fields"])) {
              $sParts = array();
              foreach (explode(",",$httpVars["fields"]) as $searchField) {
                  if ($searchField == "filename") {
                      $sParts[] = "basename:".$httpVars["query"];
                  } else if (in_array($searchField, $this->metaFields)) {
                      $sParts[] = "ajxp_meta_".$searchField.":".$httpVars["query"];
                  } else if ($searchField == "ajxp_document_content") {
                      $sParts[] = "title:".$httpVars["query"];
                      $sParts[] = "body:".$httpVars["query"];
                      $sParts[] = "keywords:".$httpVars["query"];
                  }
              }
              $query = implode(" OR ", $sParts);
              $query = "ajxp_scope:shared AND ($query)";
              $this->logDebug("Query : $query");
         } else {
         */
         //}
         /*
            We create this object search because it'll allow us to fetch the number of results we want at once.
            We just have to set some parameters, the query type and the size of the result set.
         */
         $search = new Elastica\Search($this->client);
         $search->addIndex($this->currentIndex)->addType($this->currentType);
         $maxResults = $this->getFilteredOption("MAX_RESULTS");
         if (isset($httpVars['limit'])) {
             $maxResults = intval($httpVars['limit']);
         }
         $searchOptions = array(\Elastica\Search::OPTION_SEARCH_TYPE => \Elastica\Search::OPTION_SEARCH_TYPE_QUERY_THEN_FETCH, \Elastica\Search::OPTION_SIZE => $maxResults);
         $this->logDebug(__FUNCTION__, "Executing query: ", $textQuery);
         $fullQuery = new Elastica\Query();
         $fullQuery->setQuery($fieldQuery);
         $qb = new Elastica\QueryBuilder();
         $fullQuery = new Elastica\Query();
         $fullQuery->setQuery($qb->query()->filtered($fieldQuery, $qb->filter()->bool()->addMust(new Elastica\Filter\Term(array("ajxp_scope" => "shared")))));
         $result = $search->search($fullQuery, $searchOptions);
         $this->logDebug(__FUNCTION__, "Search finished. ");
         $hits = $result->getResults();
         AJXP_XMLWriter::header();
         foreach ($hits as $hit) {
             $source = $hit->getSource();
             if ($source["serialized_metadata"] != null) {
                 $meta = unserialize(base64_decode($source["serialized_metadata"]));
                 $tmpNode = new AJXP_Node(SystemTextEncoding::fromUTF8($source["node_url"]), $meta);
             } else {
                 $tmpNode = new AJXP_Node(SystemTextEncoding::fromUTF8($source["node_url"]), array());
                 $tmpNode->loadNodeInfo();
             }
             if (!file_exists($tmpNode->getUrl())) {
                 $this->currentType->deleteById($hit->getId());
                 continue;
             }
             $tmpNode->search_score = sprintf("%0.2f", $hit->getScore());
             AJXP_XMLWriter::renderAjxpNode($tmpNode);
         }
         AJXP_XMLWriter::close();
     } else {
         if ($actionName == "search_by_keyword") {
             $scope = "user";
             try {
                 $this->loadIndex($repoId, false);
             } catch (Exception $ex) {
                 throw new Exception($messages["index.lucene.7"]);
             }
             $sParts = array();
             $searchField = $httpVars["field"];
             if ($scope == "user") {
                 if (AuthService::usersEnabled() && AuthService::getLoggedUser() == null) {
                     throw new Exception("Cannot find current user");
                 }
                 $sParts[] = "ajxp_scope:user";
                 $sParts[] = "ajxp_user:"******"ajxp_scope:shared";
             }
             $query = implode(" AND ", $sParts);
             $this->logDebug("Query : {$query}");
             $fieldQuery = new Elastica\Query\QueryString();
             $fields = array($searchField);
             $fieldQuery->setQuery($searchField == "ajxp_node" ? "yes" : "true");
             $fieldQuery->setFields($fields);
             $fieldQuery->setAllowLeadingWildcard(false);
             $fieldQuery->setFuzzyMinSim(0.8);
             $search = new Elastica\Search($this->client);
             $search->addIndex($this->currentIndex)->addType($this->currentType);
             $maxResults = $this->getFilteredOption("MAX_RESULTS");
             if (isset($httpVars['limit'])) {
                 $maxResults = intval($httpVars['limit']);
             }
             $searchOptions = array(\Elastica\Search::OPTION_SEARCH_TYPE => \Elastica\Search::OPTION_SEARCH_TYPE_QUERY_THEN_FETCH, \Elastica\Search::OPTION_SIZE => $maxResults);
             // ADD SCOPE FILTER
             $term = new Elastica\Filter\Term();
             $term->setTerm("ajxp_scope", "user");
             $qb = new Elastica\QueryBuilder();
             $fullQuery = new Elastica\Query();
             $fullQuery->setQuery($qb->query()->filtered($fieldQuery, $qb->filter()->bool()->addMust(new Elastica\Filter\Term(array("ajxp_scope" => "user")))->addMust(new Elastica\Filter\Term(array("user" => AuthService::getLoggedUser()->getId())))));
             $result = $search->search($fullQuery, $searchOptions);
             $this->logDebug(__FUNCTION__, "Search finished. ");
             $hits = $result->getResults();
             AJXP_XMLWriter::header();
             foreach ($hits as $hit) {
                 if ($hit->serialized_metadata != null) {
                     $meta = unserialize(base64_decode($hit->serialized_metadata));
                     $tmpNode = new AJXP_Node(SystemTextEncoding::fromUTF8($hit->node_url), $meta);
                 } else {
                     $tmpNode = new AJXP_Node(SystemTextEncoding::fromUTF8($hit->node_url), array());
                     $tmpNode->loadNodeInfo();
                 }
                 if (!file_exists($tmpNode->getUrl())) {
                     $this->currentType->deleteById($hit->id);
                     continue;
                 }
                 $tmpNode->search_score = sprintf("%0.2f", $hit->score);
                 AJXP_XMLWriter::renderAjxpNode($tmpNode);
             }
             AJXP_XMLWriter::close();
         }
     }
 }
Example #5
0
 /**
  * method to load infos about search
  *
  * @return array
  */
 function loadCartoInfos()
 {
     $search_query = new CSearchQuery();
     $query_aggreg = $search_query->aggregCartoCountByType();
     //Search on the index.
     $index = $this->loadIndex($this->loadNameIndex());
     $search = new \Elastica\Search($this->_client);
     $search->addIndex($index);
     $aggreg = $search->search($query_aggreg);
     // récupération du nombre de docs "indexés"
     $nbdocs_indexed = $index->count();
     $result["nbdocs_indexed"] = $nbdocs_indexed;
     // récupération des données de l'agregation
     $aggreg = $aggreg->getAggregation("ref_type");
     $result["aggregation"] = $aggreg["buckets"];
     return $result;
 }
 public function testMapDate()
 {
     update_option('fields', array('post_date' => 1));
     register_post_type('post');
     wp_insert_post(array('post_type' => 'post', 'post_date' => '07/30/1989 00:00:00 CST'));
     wp_insert_post(array('post_type' => 'post', 'post_date' => '10/30/1988 00:00:00 CST'));
     Indexer::_map();
     Indexer::reindex();
     $this->index->refresh();
     $search = new \Elastica\Search($this->index->getClient());
     $search->addIndex($this->index);
     $results = $search->search(new \Elastica\Query(array('sort' => array('post_date' => array('order' => 'asc')))))->getResults();
     $this->assertCount(2, $results);
     $this->assertEquals(2, $results[0]->getId());
     $this->assertEquals(1, $results[1]->getId());
     $results = $search->search(new \Elastica\Query(array('sort' => array('post_date' => array('order' => 'desc')))))->getResults();
     $this->assertCount(2, $results);
     $this->assertEquals(1, $results[0]->getId());
     $this->assertEquals(2, $results[1]->getId());
 }
 public function applyAction($actionName, $httpVars, $fileVars)
 {
     $messages = ConfService::getMessages();
     $repoId = ConfService::getRepository()->getId();
     if ($actionName == "search") {
         // TMP
         if (strpos($httpVars["query"], "keyword:") === 0) {
             $parts = explode(":", $httpVars["query"]);
             $this->applyAction("search_by_keyword", array("field" => $parts[1]), array());
             return;
         }
         if ($this->isIndexLocked($repoId)) {
             throw new Exception($messages["index.lucene.6"]);
         }
         try {
             $this->loadIndex($repoId, false);
         } catch (Exception $ex) {
             $this->applyAction("index", array(), array());
             throw new Exception($messages["index.lucene.7"]);
         }
         /*
         
         if ((isSet($this->metaFields) || $this->indexContent) && isSet($httpVars["fields"])) {
              $sParts = array();
              foreach (explode(",",$httpVars["fields"]) as $searchField) {
                  if ($searchField == "filename") {
                      $sParts[] = "basename:".$httpVars["query"];
                  } else if (in_array($searchField, $this->metaFields)) {
                      $sParts[] = "ajxp_meta_".$searchField.":".$httpVars["query"];
                  } else if ($searchField == "ajxp_document_content") {
                      $sParts[] = "title:".$httpVars["query"];
                      $sParts[] = "body:".$httpVars["query"];
                      $sParts[] = "keywords:".$httpVars["query"];
                  }
              }
              $query = implode(" OR ", $sParts);
              $query = "ajxp_scope:shared AND ($query)";
              $this->logDebug("Query : $query");
         } else {
         */
         $this->currentIndex->open();
         $query = $httpVars["query"];
         $fieldQuery = new Elastica\Query\Field();
         //}
         //$this->setDefaultAnalyzer();
         if ($query == "*") {
             $fieldQuery->setField("ajxp_node");
             $fieldQuery->setQueryString("yes");
         } else {
             $fieldQuery->setField("basename");
             $fieldQuery->setQueryString($query);
         }
         /*
            We create this object search because it'll allow us to fetch the number of results we want at once.
            We just have to set some parameters, the query type and the size of the result set.
         */
         $search = new Elastica\Search($this->client);
         $search->addIndex($this->currentIndex)->addType($this->currentType);
         $maxResults = $this->getFilteredOption("MAX_RESULTS");
         $searchOptions = array(\Elastica\Search::OPTION_SEARCH_TYPE => \Elastica\Search::OPTION_SEARCH_TYPE_QUERY_THEN_FETCH, \Elastica\Search::OPTION_SIZE => $maxResults);
         $result = $search->search($fieldQuery, $searchOptions);
         $total_hits = $result->getTotalHits();
         $hits = $result->getResults();
         AJXP_XMLWriter::header();
         for ($i = 0, $count = count($hits); $i < $count; $i++) {
             $hit = $hits[$i];
             $source = $hit->getSource();
             if ($source["serialized_metadata"] != null) {
                 $meta = unserialize(base64_decode($source["serialized_metadata"]));
                 $tmpNode = new AJXP_Node(SystemTextEncoding::fromUTF8($source["node_url"]), $meta);
             } else {
                 $tmpNode = new AJXP_Node(SystemTextEncoding::fromUTF8($source["node_url"]), array());
                 $tmpNode->loadNodeInfo();
             }
             if (!file_exists($tmpNode->getUrl())) {
                 $this->currentType->deleteById($hit->getId());
                 continue;
             }
             $tmpNode->search_score = sprintf("%0.2f", $hit->getScore());
             AJXP_XMLWriter::renderAjxpNode($tmpNode);
         }
         AJXP_XMLWriter::close();
         $this->currentIndex->close();
     } else {
         if ($actionName == "search_by_keyword") {
             /*    require_once("Zend/Search/Lucene.php");
                         $scope = "user";
             
                         if ($this->isIndexLocked(ConfService::getRepository()->getId())) {
                             throw new Exception($messages["index.lucene.6"]);
                         }
                         try {
                             $this->currentInd =  $this->loadIndex(ConfService::getRepository()->getId(), false);
                         } catch (Exception $ex) {
                             $this->applyAction("index", array(), array());
                             throw new Exception($messages["index.lucene.7"]);
                         }
                         $sParts = array();
                         $searchField = $httpVars["field"];
                         if ($searchField == "ajxp_node") {
                             $sParts[] = "$searchField:yes";
                         } else {
                             $sParts[] = "$searchField:true";
                         }
                         if ($scope == "user") {
                             if (AuthService::usersEnabled() && AuthService::getLoggedUser() == null) {
                                 throw new Exception("Cannot find current user");
                             }
                             $sParts[] = "ajxp_scope:user";
                             $sParts[] = "ajxp_user:"******"ajxp_scope:shared";
                         }
                         $query = implode(" AND ", $sParts);
                         $this->logDebug("Query : $query");
                         $hits = $this->currentIndex->find($query);
             
                         $commitIndex = false;
             
                         AJXP_XMLWriter::header();
                         foreach ($hits as $hit) {
                             if ($hit->serialized_metadata!=null) {
                                 $meta = unserialize(base64_decode($hit->serialized_metadata));
                                 $tmpNode = new AJXP_Node(SystemTextEncoding::fromUTF8($hit->node_url), $meta);
                             } else {
                                 $tmpNode = new AJXP_Node(SystemTextEncoding::fromUTF8($hit->node_url), array());
                                 $tmpNode->loadNodeInfo();
                             }
                             if (!file_exists($tmpNode->getUrl())) {
                                 $this->currentIndex->delete($hit->id);
                                 $commitIndex = true;
                                 continue;
                             }
                             $tmpNode->search_score = sprintf("%0.2f", $hit->score);
                             AJXP_XMLWriter::renderAjxpNode($tmpNode);
                         }
                         AJXP_XMLWriter::close();
                         if ($commitIndex) {
                             $this->currentIndex->commit();
                         }*/
         } else {
             if ($actionName == "index") {
                 $dir = AJXP_Utils::decodeSecureMagic($httpVars["dir"]);
                 if (empty($dir)) {
                     $dir = "/";
                 }
                 $repo = ConfService::getRepository();
                 if ($this->isIndexLocked($repo->getId())) {
                     throw new Exception($messages["index.lucene.6"]);
                 }
                 $accessType = $repo->getAccessType();
                 $accessPlug = AJXP_PluginsService::getInstance()->getPluginByTypeName("access", $accessType);
                 $stData = $accessPlug->detectStreamWrapper(true);
                 $repoId = $repo->getId();
                 $url = $stData["protocol"] . "://" . $repoId . $dir;
                 if (isset($httpVars["verbose"]) && $httpVars["verbose"] == "true") {
                     $this->verboseIndexation = true;
                 }
                 if (ConfService::backgroundActionsSupported() && !ConfService::currentContextIsCommandLine()) {
                     AJXP_Controller::applyActionInBackground($repoId, "index", $httpVars);
                     AJXP_XMLWriter::header();
                     AJXP_XMLWriter::triggerBgAction("check_lock", array("repository_id" => $repoId), sprintf($messages["index.lucene.8"], $dir), true, 2);
                     AJXP_XMLWriter::close();
                     return;
                 }
                 $this->lockIndex($repoId);
                 // GIVE BACK THE HAND TO USER
                 session_write_close();
                 $this->loadIndex($repoId);
                 $this->currentIndex->open();
                 $this->recursiveIndexation($url);
                 if (ConfService::currentContextIsCommandLine() && $this->verboseIndexation) {
                     print "Optimizing\n";
                     $this->currentIndex->optimize();
                 }
                 $this->currentIndex->close();
                 $this->currentIndex = null;
                 $this->releaseLock($repoId);
             } else {
                 if ($actionName == "check_lock") {
                     $repoId = $httpVars["repository_id"];
                     if ($this->isIndexLocked($repoId)) {
                         AJXP_XMLWriter::header();
                         AJXP_XMLWriter::triggerBgAction("check_lock", array("repository_id" => $repoId), $messages["index.lucene.10"], true, 3);
                         AJXP_XMLWriter::close();
                     } else {
                         AJXP_XMLWriter::header();
                         AJXP_XMLWriter::triggerBgAction("info_message", array(), $messages["index.lucene.5"], true, 5);
                         AJXP_XMLWriter::close();
                     }
                 }
             }
         }
     }
 }
 /**
  * @param $queryString
  * @param int $offset
  * @param int $limit
  * @return null|SugarSeachEngineElasticResultSet
  */
 public function search($queryString, $offset = 0, $limit = 20, $options = array())
 {
     if (self::isSearchEngineDown()) {
         return null;
     }
     $appendWildcard = false;
     if (!empty($options['append_wildcard']) && $this->canAppendWildcard($queryString)) {
         $appendWildcard = true;
     }
     $queryString = DBManagerFactory::getInstance()->sqlLikeString($queryString, self::WILDCARD_CHAR, $appendWildcard);
     $this->logger->info("Going to search with query {$queryString}");
     $results = null;
     try {
         $queryObj = $this->buildQueryObject($queryString, $options);
         $s = new \Elastica\Search($this->_client);
         $finalTypes = array();
         if (!empty($options['moduleFilter'])) {
             foreach ($options['moduleFilter'] as $moduleName) {
                 // only add the module to the list if it can be viewed
                 if ($this->checkAccess($moduleName)) {
                     $finalTypes[] = $moduleName;
                 }
             }
             if (!empty($finalTypes)) {
                 $s->addTypes($finalTypes);
             }
         }
         $s->addIndices($this->getReadIndices($finalTypes));
         // main filter
         $mainFilter = $this->constructMainFilter($finalTypes, $options);
         $query = new \Elastica\Query($queryObj);
         $query->setFilter($mainFilter);
         if (isset($options['sort']) && is_array($options['sort'])) {
             foreach ($options['sort'] as $sort) {
                 $query->addSort($sort);
             }
         }
         $query->setParam('from', $offset);
         // set query highlight
         $fields = $this->getSearchFields($options, false);
         $highlighArray = $this->constructHighlightArray($fields, $options);
         $query->setHighlight($highlighArray);
         // add facets
         $this->addFacets($query, $options, $mainFilter);
         $esResultSet = $s->search($query, $limit);
         $results = new SugarSeachEngineElasticResultSet($esResultSet);
     } catch (Exception $e) {
         $this->reportException("Unable to perform search", $e);
         $this->checkException($e);
         return null;
     }
     return $results;
 }
Example #9
0
 /**
  * Method to load infos about serveur ES
  *
  * @return array
  */
 function loadCartoInfos()
 {
     $query = new CSearchQuery();
     $query_aggreg = $query->aggregCartoCountByType();
     //Search on the index.
     $this->_index = $this->loadIndex();
     $search = new \Elastica\Search($this->_client);
     $search->addIndex($this->_index);
     return $query->loadCartoInfos($this, $search->search($query_aggreg));
 }