diff options
Diffstat (limited to 'vendor/ruflin/elastica/lib/Elastica/Search.php')
-rw-r--r-- | vendor/ruflin/elastica/lib/Elastica/Search.php | 553 |
1 files changed, 553 insertions, 0 deletions
diff --git a/vendor/ruflin/elastica/lib/Elastica/Search.php b/vendor/ruflin/elastica/lib/Elastica/Search.php new file mode 100644 index 00000000..7306eb75 --- /dev/null +++ b/vendor/ruflin/elastica/lib/Elastica/Search.php @@ -0,0 +1,553 @@ +<?php +namespace Elastica; + +use Elastica\Exception\InvalidException; + +/** + * Elastica search object. + * + * @author Nicolas Ruflin <spam@ruflin.com> + */ +class Search +{ + /* + * Options + */ + const OPTION_SEARCH_TYPE = 'search_type'; + const OPTION_ROUTING = 'routing'; + const OPTION_PREFERENCE = 'preference'; + const OPTION_VERSION = 'version'; + const OPTION_TIMEOUT = 'timeout'; + const OPTION_FROM = 'from'; + const OPTION_SIZE = 'size'; + const OPTION_SCROLL = 'scroll'; + const OPTION_SCROLL_ID = 'scroll_id'; + const OPTION_QUERY_CACHE = 'query_cache'; + + /* + * Search types + */ + const OPTION_SEARCH_TYPE_COUNT = 'count'; + const OPTION_SEARCH_TYPE_SCAN = 'scan'; + const OPTION_SEARCH_TYPE_DFS_QUERY_THEN_FETCH = 'dfs_query_then_fetch'; + const OPTION_SEARCH_TYPE_DFS_QUERY_AND_FETCH = 'dfs_query_and_fetch'; + const OPTION_SEARCH_TYPE_QUERY_THEN_FETCH = 'query_then_fetch'; + const OPTION_SEARCH_TYPE_QUERY_AND_FETCH = 'query_and_fetch'; + const OPTION_SEARCH_TYPE_SUGGEST = 'suggest'; + const OPTION_SEARCH_TYPE_SCROLL = 'scroll'; + const OPTION_SEARCH_IGNORE_UNAVAILABLE = 'ignore_unavailable'; + + /** + * Array of indices. + * + * @var array + */ + protected $_indices = array(); + + /** + * Array of types. + * + * @var array + */ + protected $_types = array(); + + /** + * @var \Elastica\Query + */ + protected $_query; + + /** + * @var array + */ + protected $_options = array(); + + /** + * Client object. + * + * @var \Elastica\Client + */ + protected $_client; + + /** + * Constructs search object. + * + * @param \Elastica\Client $client Client object + */ + public function __construct(Client $client) + { + $this->_client = $client; + } + + /** + * Adds a index to the list. + * + * @param \Elastica\Index|string $index Index object or string + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function addIndex($index) + { + if ($index instanceof Index) { + $index = $index->getName(); + } + + if (!is_scalar($index)) { + throw new InvalidException('Invalid param type'); + } + + $this->_indices[] = (string) $index; + + return $this; + } + + /** + * Add array of indices at once. + * + * @param array $indices + * + * @return $this + */ + public function addIndices(array $indices = array()) + { + foreach ($indices as $index) { + $this->addIndex($index); + } + + return $this; + } + + /** + * Adds a type to the current search. + * + * @param \Elastica\Type|string $type Type name or object + * + * @throws \Elastica\Exception\InvalidException + * + * @return $this + */ + public function addType($type) + { + if ($type instanceof Type) { + $type = $type->getName(); + } + + if (!is_string($type)) { + throw new InvalidException('Invalid type type'); + } + + $this->_types[] = $type; + + return $this; + } + + /** + * Add array of types. + * + * @param array $types + * + * @return $this + */ + public function addTypes(array $types = array()) + { + foreach ($types as $type) { + $this->addType($type); + } + + return $this; + } + + /** + * @param string|array|\Elastica\Query|\Elastica\Suggest|\Elastica\Query\AbstractQuery|\Elastica\Filter\AbstractFilter $query| + * + * @return $this + */ + public function setQuery($query) + { + $this->_query = Query::create($query); + + return $this; + } + + /** + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function setOption($key, $value) + { + $this->_validateOption($key); + + $this->_options[$key] = $value; + + return $this; + } + + /** + * @param array $options + * + * @return $this + */ + public function setOptions(array $options) + { + $this->clearOptions(); + + foreach ($options as $key => $value) { + $this->setOption($key, $value); + } + + return $this; + } + + /** + * @return $this + */ + public function clearOptions() + { + $this->_options = array(); + + return $this; + } + + /** + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function addOption($key, $value) + { + $this->_validateOption($key); + + if (!isset($this->_options[$key])) { + $this->_options[$key] = array(); + } + + $this->_options[$key][] = $value; + + return $this; + } + + /** + * @param string $key + * + * @return bool + */ + public function hasOption($key) + { + return isset($this->_options[$key]); + } + + /** + * @param string $key + * + * @throws \Elastica\Exception\InvalidException + * + * @return mixed + */ + public function getOption($key) + { + if (!$this->hasOption($key)) { + throw new InvalidException('Option '.$key.' does not exist'); + } + + return $this->_options[$key]; + } + + /** + * @return array + */ + public function getOptions() + { + return $this->_options; + } + + /** + * @param string $key + * + * @throws \Elastica\Exception\InvalidException + * + * @return bool + */ + protected function _validateOption($key) + { + switch ($key) { + case self::OPTION_SEARCH_TYPE: + case self::OPTION_ROUTING: + case self::OPTION_PREFERENCE: + case self::OPTION_VERSION: + case self::OPTION_TIMEOUT: + case self::OPTION_FROM: + case self::OPTION_SIZE: + case self::OPTION_SCROLL: + case self::OPTION_SCROLL_ID: + case self::OPTION_SEARCH_TYPE_SUGGEST: + case self::OPTION_SEARCH_IGNORE_UNAVAILABLE: + case self::OPTION_QUERY_CACHE: + return true; + } + + throw new InvalidException('Invalid option '.$key); + } + + /** + * Return client object. + * + * @return \Elastica\Client Client object + */ + public function getClient() + { + return $this->_client; + } + + /** + * Return array of indices. + * + * @return array List of index names + */ + public function getIndices() + { + return $this->_indices; + } + + /** + * @return bool + */ + public function hasIndices() + { + return count($this->_indices) > 0; + } + + /** + * @param Index|string $index + * + * @return bool + */ + public function hasIndex($index) + { + if ($index instanceof Index) { + $index = $index->getName(); + } + + return in_array($index, $this->_indices); + } + + /** + * Return array of types. + * + * @return array List of types + */ + public function getTypes() + { + return $this->_types; + } + + /** + * @return bool + */ + public function hasTypes() + { + return count($this->_types) > 0; + } + + /** + * @param \Elastica\Type|string $type + * + * @return bool + */ + public function hasType($type) + { + if ($type instanceof Type) { + $type = $type->getName(); + } + + return in_array($type, $this->_types); + } + + /** + * @return \Elastica\Query + */ + public function getQuery() + { + if (null === $this->_query) { + $this->_query = Query::create(''); + } + + return $this->_query; + } + + /** + * Creates new search object. + * + * @param \Elastica\SearchableInterface $searchObject + * + * @return Search + */ + public static function create(SearchableInterface $searchObject) + { + return $searchObject->createSearch(); + } + + /** + * Combines indices and types to the search request path. + * + * @return string Search path + */ + public function getPath() + { + if (isset($this->_options[self::OPTION_SCROLL_ID])) { + return '_search/scroll'; + } + + $indices = $this->getIndices(); + + $path = ''; + $types = $this->getTypes(); + + if (empty($indices)) { + if (!empty($types)) { + $path .= '_all'; + } + } else { + $path .= implode(',', $indices); + } + + if (!empty($types)) { + $path .= '/'.implode(',', $types); + } + + // Add full path based on indices and types -> could be all + return $path.'/_search'; + } + + /** + * Search in the set indices, types. + * + * @param mixed $query + * @param int|array $options OPTIONAL Limit or associative array of options (option=>value) + * + * @throws \Elastica\Exception\InvalidException + * + * @return \Elastica\ResultSet + */ + public function search($query = '', $options = null) + { + $this->setOptionsAndQuery($options, $query); + + $query = $this->getQuery(); + $path = $this->getPath(); + + $params = $this->getOptions(); + + // Send scroll_id via raw HTTP body to handle cases of very large (> 4kb) ids. + if ('_search/scroll' == $path) { + $data = $params[self::OPTION_SCROLL_ID]; + unset($params[self::OPTION_SCROLL_ID]); + } else { + $data = $query->toArray(); + } + + $response = $this->getClient()->request( + $path, + Request::GET, + $data, + $params + ); + + return ResultSet::create($response, $query); + } + + /** + * @param mixed $query + * @param $fullResult (default = false) By default only the total hit count is returned. If set to true, the full ResultSet including aggregations is returned. + * + * @return int|ResultSet + */ + public function count($query = '', $fullResult = false) + { + $this->setOptionsAndQuery(null, $query); + + $query = $this->getQuery(); + $path = $this->getPath(); + + $response = $this->getClient()->request( + $path, + Request::GET, + $query->toArray(), + array(self::OPTION_SEARCH_TYPE => self::OPTION_SEARCH_TYPE_COUNT) + ); + $resultSet = ResultSet::create($response, $query); + + return $fullResult ? $resultSet : $resultSet->getTotalHits(); + } + + /** + * @param array|int $options + * @param string|array|\Elastica\Query $query + * + * @return $this + */ + public function setOptionsAndQuery($options = null, $query = '') + { + if ('' != $query) { + $this->setQuery($query); + } + + if (is_int($options)) { + $this->getQuery()->setSize($options); + } elseif (is_array($options)) { + if (isset($options['limit'])) { + $this->getQuery()->setSize($options['limit']); + unset($options['limit']); + } + if (isset($options['explain'])) { + $this->getQuery()->setExplain($options['explain']); + unset($options['explain']); + } + $this->setOptions($options); + } + + return $this; + } + + /** + * @param Suggest $suggest + * + * @return $this + */ + public function setSuggest(Suggest $suggest) + { + return $this->setOptionsAndQuery(array(self::OPTION_SEARCH_TYPE_SUGGEST => 'suggest'), $suggest); + } + + /** + * Returns the Scroll Iterator. + * + * @see Elastica\Scroll + * + * @param string $expiryTime + * + * @return Scroll + */ + public function scroll($expiryTime = '1m') + { + return new Scroll($this, $expiryTime); + } + + /** + * Returns the ScanAndScroll Iterator. + * + * @see Elastica\ScanAndScroll + * + * @param string $expiryTime + * @param int $sizePerShard + * + * @return ScanAndScroll + */ + public function scanAndScroll($expiryTime = '1m', $sizePerShard = 1000) + { + return new ScanAndScroll($this, $expiryTime, $sizePerShard); + } +} |