Commit 184cace6 authored by Bas de Nooijer's avatar Bas de Nooijer

Implemented minimumscorefilter plugin, including an example

parent 41586730
<?php
require(__DIR__.'/init.php');
htmlHeader();
// create a client instance
$client = new Solarium\Client($config);
// enable the plugin and get a query instance
$filter = $client->getPlugin('minimumscorefilter');
$query = $client->createQuery($filter::QUERY_TYPE);
$query->setQuery('a');
$query->setFields(array('id'));
$query->setFilterRatio(.5);
$query->setFilterMode($query::FILTER_MODE_MARK);
// this executes the query and returns the result
$resultset = $client->execute($query);
// display the total number of documents found by solr and the maximum score
echo 'NumFound: '.$resultset->getNumFound();
echo '<br/>MaxScore: '.$resultset->getMaxScore();
// show documents using the resultset iterator
foreach ($resultset as $document) {
// by setting the FILTER_MARK option we get a special method to test each document
if ($document->markedAsLowScore()) {
echo '<hr/><b>MARKED AS LOW SCORE</b><table>';
} else {
echo '<hr/><table>';
}
// the documents are also iterable, to get all fields
foreach ($document as $field => $value) {
// this converts multivalue fields to a comma-separated string
if (is_array($value)) {
$value = implode(', ', $value);
}
echo '<tr><th>' . $field . '</th><td>' . $value . '</td></tr>';
}
echo '</table>';
}
htmlFooter();
...@@ -130,6 +130,7 @@ ...@@ -130,6 +130,7 @@
<li><a href="7.4-plugin-parallelexecution.php">7.4 Parallel Execution</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.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> <li><a href="7.6-plugin-prefetchiterator.php">7.6 Prefetch iterator for select queries</a></li>
<li><a href="7.7-plugin-minimumscorefilter.php">7.7 Minimum score filter for select queries</a></li>
</ul> </ul>
</ul> </ul>
......
...@@ -169,6 +169,7 @@ class Client extends Configurable ...@@ -169,6 +169,7 @@ class Client extends Configurable
'parallelexecution' => 'Solarium\Plugin\ParallelExecution\ParallelExecution', 'parallelexecution' => 'Solarium\Plugin\ParallelExecution\ParallelExecution',
'bufferedadd' => 'Solarium\Plugin\BufferedAdd\BufferedAdd', 'bufferedadd' => 'Solarium\Plugin\BufferedAdd\BufferedAdd',
'prefetchiterator' => 'Solarium\Plugin\PrefetchIterator', 'prefetchiterator' => 'Solarium\Plugin\PrefetchIterator',
'minimumscorefilter' => 'Solarium\Plugin\MinimumScoreFilter\MinimumScoreFilter',
); );
/** /**
......
<?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/
*/
/**
* @namespace
*/
namespace Solarium\Plugin\MinimumScoreFilter;
use Solarium\QueryType\Select\Result\DocumentInterface;
/**
* Minimum score filter query result document
*
* Decorates the original document with a filter indicator
*/
class Document implements \IteratorAggregate, \Countable, \ArrayAccess
{
/**
* Original document
*
* @var array
*/
protected $document;
/**
* Is this document marked as a low score?
*
* @var boolean
*/
protected $marked;
/**
* Constructor
*
* @param DocumentInterface $fields
*/
public function __construct(DocumentInterface $document, $threshold)
{
$this->document = $document;
$this->marked = $threshold > $document->score;
}
/**
* Get markedAsLowScore status
*
* @return bool
*/
public function markedAsLowScore()
{
return $this->marked;
}
/**
* Forward all other calls to the original document
*
* @param string $name
* @param array $arguments
* @return mixed
*/
public function __call($name, $arguments) {
return $this->document->$name($arguments);
}
/**
* Forward all other calls to the original document
*
* @param string $name
* @return mixed
*/
public function __get($name) {
return parent::__get($name);
}
/**
* IteratorAggregate implementation
*
* @return \ArrayIterator
*/
public function getIterator()
{
return $this->document->getIterator();
}
/**
* Countable implementation
*
* @return int
*/
public function count()
{
return $this->document->count();
}
/**
* ArrayAccess implementation
*
* @param mixed $offset
* @param mixed $value
* @return void
*/
public function offsetSet($offset, $value)
{
return $this->document->offsetGet($offset, $value);
}
/**
* ArrayAccess implementation
*
* @param mixed $offset
* @return bool
*/
public function offsetExists($offset)
{
return $this->document->offsetExists($offset);
}
/**
* ArrayAccess implementation
*
* @param mixed $offset
* @return void
*/
public function offsetUnset($offset)
{
$this->document->offsetUnset($offset);
}
/**
* ArrayAccess implementation
*
* @param mixed $offset
* @return mixed|null
*/
public function offsetGet($offset)
{
return $this->document->offsetGet($offset);
}
}
<?php
/**
* Copyright 2014 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 2014 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
* @link http://www.solarium-project.org/
*/
/**
* @namespace
*/
namespace Solarium\Plugin\MinimumScoreFilter;
use Solarium\Core\Plugin\Plugin;
/**
* PostBigRequest plugin
*
* If you reach the url/header length limit of your servlet container your queries will fail.
* You can increase the limit in the servlet container, but if that's not possible this plugin can automatically
* convert big GET requests into POST requests. A POST request (usually) has a much higher limit.
*
* The default maximum querystring length is 1024. This doesn't include the base url or headers.
* For most servlet setups this limit leaves enough room for that extra data. Adjust the limit if needed.
*/
class MinimumScoreFilter extends Plugin
{
/**
* Custom query type name
*/
const QUERY_TYPE = 'minimum-score-select';
/**
* Plugin init function
*
* Register event listeners
*
* @return void
*/
protected function initPluginType()
{
$this->client->registerQueryType(self::QUERY_TYPE, 'Solarium\Plugin\MinimumScoreFilter\Query');
}
}
<?php
/**
* Copyright 2014 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/
*/
/**
* @namespace
*/
namespace Solarium\Plugin\MinimumScoreFilter;
use Solarium\QueryType\Select\Query\Query as SelectQuery;
/**
* MinimumScoreFilter Query
*
* Extends the standard select query and adds functionality for the minimumscore filter
*/
class Query extends SelectQuery
{
/**
* Filter mode mark documents
*/
const FILTER_MODE_MARK = 'mark';
/**
* Filter mode remove documents
*/
const FILTER_MODE_REMOVE = 'remove';
/**
* Default options
*
* @var array
*/
protected $options = array(
'handler' => 'select',
'resultclass' => 'Solarium\QueryType\Select\Result\Result',
'documentclass' => 'Solarium\QueryType\Select\Result\Document',
'query' => '*:*',
'start' => 0,
'rows' => 10,
'fields' => '*,score',
'omitheader' => true,
'filterratio' => 0.1,
'filter_mode' => self::FILTER_MODE_REMOVE,
);
/**
* Set filter mode
*
* @param string $value
* @return self Provides fluent interface
*/
public function setFilterMode($mode)
{
return $this->setOption('filter_mode', $mode);
}
/**
* Get filter mode
*
* @return string
*/
public function getFilterMode()
{
return $this->getOption('filter_mode');
}
/**
* Set filterratio option
*
* This should be a ratio between 0 and 1, the minimum score is calculated by multiplying maxscore with this ratio.
*
* @param float $value
* @return self Provides fluent interface
*/
public function setFilterRatio($value)
{
return $this->setOption('filterratio', $value);
}
/**
* Get filterratio option
*
* @return float
*/
public function getFilterRatio()
{
return $this->getOption('filterratio');
}
/**
* Make sure the score field is always enabled
*
* @return array
*/
public function getFields()
{
$fields = parent::getFields();
if (!in_array('score', $fields)) {
$fields[] = 'score';
}
return $fields;
}
/**
* Make sure the filtering result class is always used
*
* @return string
*/
public function getResultClass()
{
return 'Solarium\Plugin\MinimumScoreFilter\Result';
}
}
<?php
/**
* Copyright 2014 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 2014 Bas de Nooijer <solarium@raspberry.nl>
* @license http://github.com/basdenooijer/solarium/raw/master/COPYING
* @link http://www.solarium-project.org/
*/
/**
* @namespace
*/
namespace Solarium\Plugin\MinimumScoreFilter;
use Solarium\QueryType\Select\Result\Result as SelectResult;
/**
* Minimumscore filter query result
*
* Extends select query result, adds filtering / marking
*
*/
class Result extends SelectResult
{
/**
* Map parser data into properties
*
* @param array $mapData
* @return void
*/
protected function mapData($mapData)
{
foreach ($mapData as $key => $data) {
if ($key == 'documents') {
$data = $this->filterDocuments($data, $mapData['maxscore']);
}
$this->$key = $data;
}
}
/**
* Apply filter to document array
*
* @param array $documents
* @param float $maxScore
* @return array
*/
protected function filterDocuments($documents, $maxScore)
{
$mode = $this->getQuery()->getFilterMode();
$ratio = $this->getQuery()->getFilterRatio();
$threshold = $maxScore * $ratio;
switch ($mode) {
case Query::FILTER_MODE_REMOVE:
foreach ($documents as $key => $document) {
if ($document->score < $threshold) {
unset($documents[$key]);
}
}
break;
case Query::FILTER_MODE_MARK:
foreach ($documents as $key => $document) {
$documents[$key] = new Document($document, $threshold);
}
break;
default:
throw new \OutOfBoundsException('Unknown filter mode in query: ' . $mode);
break;
}
return $documents;
}
}
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