Commit d26d3af9 authored by Bas de Nooijer's avatar Bas de Nooijer

Added PrefetchIterator plugin including a usage example

parent f64135cd
<?php
require('init.php');
htmlHeader();
// create a client instance
$client = new Solarium_Client($config);
// get a select query instance
$query = $client->createSelect();
$query->setFields(array('id'));
// get a plugin instance and apply settings
$prefetch = $client->getPlugin('prefetchiterator');
$prefetch->setPrefetch(2); //fetch 5 rows per query (for real world use this can be way higher)
$prefetch->setQuery($query);
// display the total number of documents found by solr
echo 'NumFound: ' . count($prefetch);
// show document IDs using the resultset iterator
foreach ($prefetch as $document) {
echo '<hr/>ID: '. $document->id;
}
htmlFooter();
\ No newline at end of file
......@@ -125,6 +125,7 @@
<li><a href="7.3-plugin-customizerequest.php">7.3 Customize Requests</a></li>
<li><a href="7.4-plugin-parallelexecution.php">7.4 Parallel Execution</a></li>
<li><a href="7.5-plugin-bufferedadd.php">7.5 Buffered Add for documents</a></li>
<li><a href="7.6-plugin-prefetchiterator.php">7.6 Prefetch iterator for select queries</a></li>
</ul>
</ul>
......
......@@ -165,6 +165,7 @@ class Solarium_Client extends Solarium_Configurable
'customizerequest' => 'Solarium_Plugin_CustomizeRequest',
'parallelexecution' => 'Solarium_Plugin_ParallelExecution',
'bufferedadd' => 'Solarium_Plugin_BufferedAdd',
'prefetchiterator' => 'Solarium_Plugin_PrefetchIterator',
);
/**
......
<?php
/**
* Copyright 2011 Bas de Nooijer. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this listof conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the copyright holder.
*
* @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
* @link http://www.solarium-project.org/
*
* @package Solarium
*/
/**
* Prefetch plugin
*
* This plugin can be used to create an 'endless' iterator over a complete resultset. The iterator will take care of
* fetching the data in sets (sequential prefetching).
*
* @package Solarium
* @subpackage Plugin
*/
class Solarium_Plugin_PrefetchIterator extends Solarium_Plugin_Abstract implements Iterator, Countable
{
/**
* Default options
*
* @var array
*/
protected $_options = array(
'prefetch' => 100,
);
/**
* @var Solarium_Query_Select
*/
protected $_query;
/**
* @var int
*/
protected $_start = 0;
/**
* @var Solarium_Result_Select
*/
protected $_result;
/**
* Iterator position
*
* @var int
*/
protected $_position;
/**
* @var array
*/
protected $_documents;
/**
* Set prefetch option
*
* @param integer $value
* @return self Provides fluent interface
*/
public function setPrefetch($value)
{
return $this->_setOption('prefetch', $value);
}
/**
* Get prefetch option
*
* @return integer
*/
public function getPrefetch()
{
return $this->getOption('prefetch');
}
/**
* Set query to use for prefetching
*
* @param Solarium_Query_Select $query
* @return self Provides fluent interface
*/
public function setQuery($query)
{
$this->_query = $query;
return $this;
}
/**
* Get the query object used
*
* @return Solarium_Query_Select
*/
public function getQuery()
{
return $this->_query;
}
/**
* Countable implementation
*
* @return int
*/
public function count()
{
// if no results are available yet, get them now
if (null == $this->_result) $this->_fetchNext();
return $this->_result->getNumFound();
}
/**
* Iterator implementation
*/
function rewind() {
$this->_position = 0;
// this condition prevent useless re-fetching of data if a count is done before the iterator is used
if($this->_start !== $this->_options['prefetch']) {
$this->_start = 0;
}
}
/**
* Iterator implementation
*/
function current()
{
$adjustedIndex = $this->_position % $this->_options['prefetch'];
return $this->_documents[$adjustedIndex];
}
/**
* Iterator implementation
*
* @return int
*/
function key()
{
return $this->_position;
}
/**
* Iterator implementation
*/
function next()
{
++$this->_position;
}
/**
* Iterator implementation
*
* @return boolean
*/
function valid()
{
$adjustedIndex = $this->_position % $this->_options['prefetch'];
// this condition prevent useless re-fetching of data if a count is done before the iterator is used
if ($adjustedIndex == 0 && ($this->_position !== 0 || null == $this->_result)) {
$this->_fetchNext();
}
return isset($this->_documents[$adjustedIndex]);
}
/**
* Fetch the next set of results
*
* @return void
*/
protected function _fetchNext()
{
$this->_query->setStart($this->_start)->setRows($this->getPrefetch());
$this->_result = $this->_client->execute($this->_query);
$this->_documents = $this->_result->getDocuments();
$this->_start += $this->getPrefetch();
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment