* * @link http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html */ class Scroll implements \Iterator { /** * @var string */ public $expiryTime; /** * @var Search */ protected $_search; /** * @var null|string */ protected $_nextScrollId = null; /** * @var null|ResultSet */ protected $_currentResultSet = null; /** * 0: scroll
* 1: scroll id
* 2: search type. * * @var array */ protected $_options = array(null, null, null); /** * Constructor. * * @param Search $search * @param string $expiryTime */ public function __construct(Search $search, $expiryTime = '1m') { $this->_search = $search; $this->expiryTime = $expiryTime; } /** * Returns current result set. * * @link http://php.net/manual/en/iterator.current.php * * @return ResultSet */ public function current() { return $this->_currentResultSet; } /** * Next scroll search. * * @link http://php.net/manual/en/iterator.next.php */ public function next() { $this->_saveOptions(); $this->_search->setOption(Search::OPTION_SCROLL, $this->expiryTime); $this->_search->setOption(Search::OPTION_SCROLL_ID, $this->_nextScrollId); $this->_search->setOption(Search::OPTION_SEARCH_TYPE, Search::OPTION_SEARCH_TYPE_SCROLL); $this->_setScrollId($this->_search->search()); $this->_revertOptions(); } /** * Returns scroll id. * * @link http://php.net/manual/en/iterator.key.php * * @return string */ public function key() { return $this->_nextScrollId; } /** * Returns true if current result set contains at least one hit. * * @link http://php.net/manual/en/iterator.valid.php * * @return bool */ public function valid() { return $this->_nextScrollId !== null && $this->_currentResultSet !== null && $this->_currentResultSet->count() > 0; } /** * Initial scroll search. * * @link http://php.net/manual/en/iterator.rewind.php */ public function rewind() { // reset state $this->_nextScrollId = null; $this->_options = array(null, null, null); // initial search $this->_saveOptions(); $this->_search->setOption(Search::OPTION_SCROLL, $this->expiryTime); $this->_search->setOption(Search::OPTION_SCROLL_ID, null); $this->_search->setOption(Search::OPTION_SEARCH_TYPE, null); $this->_setScrollId($this->_search->search()); $this->_revertOptions(); } /** * Prepares Scroll for next request. * * @param ResultSet $resultSet */ protected function _setScrollId(ResultSet $resultSet) { $this->_currentResultSet = $resultSet; $this->_nextScrollId = null; if ($resultSet->getResponse()->isOk()) { $this->_nextScrollId = $resultSet->getResponse()->getScrollId(); } } /** * Save all search options manipulated by Scroll. */ protected function _saveOptions() { if ($this->_search->hasOption(Search::OPTION_SCROLL)) { $this->_options[0] = $this->_search->getOption(Search::OPTION_SCROLL); } if ($this->_search->hasOption(Search::OPTION_SCROLL_ID)) { $this->_options[1] = $this->_search->getOption(Search::OPTION_SCROLL_ID); } if ($this->_search->hasOption(Search::OPTION_SEARCH_TYPE)) { $this->_options[2] = $this->_search->getOption(Search::OPTION_SEARCH_TYPE); } } /** * Revert search options to previously saved state. */ protected function _revertOptions() { $this->_search->setOption(Search::OPTION_SCROLL, $this->_options[0]); $this->_search->setOption(Search::OPTION_SCROLL_ID, $this->_options[1]); $this->_search->setOption(Search::OPTION_SEARCH_TYPE, $this->_options[2]); } }