Commit 0ee858bd authored by Bas de Nooijer's avatar Bas de Nooijer

- MLT query now extends select query to prevent code duplication

- renamed options because the usage of dots conflicts with some config file formats
- added getters and setters for more MLT options
parent 6322500a
...@@ -49,24 +49,9 @@ ...@@ -49,24 +49,9 @@
* @package Solarium * @package Solarium
* @subpackage Query * @subpackage Query
*/ */
class Solarium_Query_MoreLikeThis extends Solarium_Query class Solarium_Query_MoreLikeThis extends Solarium_Query_Select
{ {
/**
* Query components
*/
const COMPONENT_DISMAX = 'dismax';
/**
* Query component morelikethis
*/
const COMPONENT_MORELIKETHIS = 'morelikethis';
/**
* Query component highlighting
*/
const COMPONENT_HIGHLIGHTING = 'highlighting';
/** /**
* Get type for this query * Get type for this query
* *
...@@ -76,7 +61,7 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query ...@@ -76,7 +61,7 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query
{ {
return Solarium_Client::QUERYTYPE_MORELIKETHIS; return Solarium_Client::QUERYTYPE_MORELIKETHIS;
} }
/** /**
* Default options * Default options
* *
...@@ -89,149 +74,37 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query ...@@ -89,149 +74,37 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query
'query' => '*:*', 'query' => '*:*',
'start' => 0, 'start' => 0,
'rows' => 10, 'rows' => 10,
'fl' => '*,score', 'fields' => '*,score',
'mlt.fl' => 'text', 'interestingTerms' => 'none',
'mlt.interestingTerms' => 'none', 'matchinclude' => false,
'mlt.match.include' => 'false',
'stream' => false 'stream' => false
); );
/** /**
* Default select query component types * Set query stream option
*
* @var array
*/
protected $_componentTypes = array(
self::COMPONENT_DISMAX => array(
'component' => 'Solarium_Query_Select_Component_DisMax',
'requestbuilder' => 'Solarium_Client_RequestBuilder_Select_Component_DisMax',
'responseparser' => null,
),
self::COMPONENT_MORELIKETHIS => array(
'component' => 'Solarium_Query_Select_Component_MoreLikeThis',
'requestbuilder' => 'Solarium_Client_RequestBuilder_Select_Component_MoreLikeThis',
'responseparser' => 'Solarium_Client_ResponseParser_Select_Component_MoreLikeThis',
),
self::COMPONENT_HIGHLIGHTING => array(
'component' => 'Solarium_Query_Select_Component_Highlighting',
'requestbuilder' => 'Solarium_Client_RequestBuilder_Select_Component_Highlighting',
'responseparser' => 'Solarium_Client_ResponseParser_Select_Component_Highlighting',
),
);
/**
* Fields to fetch
* *
* @var array * Set to true to post query content instead of using the URL param
*/
protected $_fields = array();
/**
* Filterqueries
* *
* @var array * @link http://wiki.apache.org/solr/ContentStream ContentStream
*/
protected $_filterQueries = array();
/**
* Search components
*
* @var array
*/
protected $_components = array();
/**
* Initialize options
* *
* Several options need some extra checks or setup work, for these options * @param boolean $stream
* the setters are called. * @return Solarium_Query_MoreLikeThis Provides fluent interface
*
* @return void
*/ */
protected function _init() public function setQueryStream($stream)
{ {
foreach ($this->_options AS $name => $value) { return $this->_setOption('stream', $stream);
switch ($name) {
case 'query':
$this->setQuery($value);
break;
case 'filterquery':
$this->addFilterQueries($value);
break;
case 'fields':
$this->addFields($value);
break;
case 'rows':
$this->setRows((int)$value);
break;
case 'start':
$this->setStart((int)$value);
break;
case 'component':
$this->_createComponents($value);
break;
}
}
} }
/** /**
* Set the query string * Get stream option
*
* Overwrites the current value. You are responsible for the correct
* escaping of user input.
* *
* @param string $query
* @param boolean $stream true for POST requests where the content-type is
* not "application/x-www-form-urlencoded", the raw POST body is passed as a stream.
* @link http://wiki.apache.org/solr/ContentStream ContentStream
* @return Solarium_Query_Select Provides fluent interface
*/
public function setQuery($query, $stream = false)
{
return $this->_setOption('stream', $stream)
->_setOption('query', trim($query));
}
/**
* @see setQuery
* @return boolean * @return boolean
*/ */
public function isStream() public function getQueryStream()
{ {
return $this->getOption('stream'); return $this->getOption('stream');
} }
/**
* Get the query string
*
* @return string
*/
public function getQuery()
{
return $this->getOption('query');
}
/**
* Set the start offset
*
* @param integer $start
* @return Solarium_Query_Select Provides fluent interface
*/
public function setStart($start)
{
return $this->_setOption('start', $start);
}
/**
* Get the start offset
*
* @return integer
*/
public function getStart()
{
return $this->getOption('start');
}
/** /**
* Set the interestingTerms parameter. Must be one of: none, list, details. * Set the interestingTerms parameter. Must be one of: none, list, details.
* *
...@@ -241,7 +114,7 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query ...@@ -241,7 +114,7 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query
*/ */
public function setInterestingTerms($term) public function setInterestingTerms($term)
{ {
return $this->_setOption('mlt.interestingTerms', $term); return $this->_setOption('interestingTerms', $term);
} }
/** /**
...@@ -251,7 +124,7 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query ...@@ -251,7 +124,7 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query
*/ */
public function getInterestingTerms() public function getInterestingTerms()
{ {
return $this->getOption('mlt.interestingTerms'); return $this->getOption('interestingTerms');
} }
/** /**
...@@ -262,7 +135,7 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query ...@@ -262,7 +135,7 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query
*/ */
public function setMatchInclude() public function setMatchInclude()
{ {
return $this->_setOption('mlt.match.include', 'true'); return $this->_setOption('matchinclude', 'true');
} }
/** /**
...@@ -272,448 +145,224 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query ...@@ -272,448 +145,224 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query
*/ */
public function getMatchInclude() public function getMatchInclude()
{ {
return $this->getOption('mlt.match.include'); return $this->getOption('matchinclude');
}
/**
* Set a custom resultclass
*
* @param string $value classname
* @return Solarium_Query_Select Provides fluent interface
*/
public function setResultClass($value)
{
return $this->_setOption('resultclass', $value);
}
/**
* Get the current resultclass option
*
* The value is a classname, not an instance
*
* @return string
*/
public function getResultClass()
{
return $this->getOption('resultclass');
}
/**
* Set a custom document class
*
* @param string $value classname
* @return Solarium_Query
*/
public function setDocumentClass($value)
{
return $this->_setOption('documentclass', $value);
}
/**
* Get the current documentclass option
*
* The value is a classname, not an instance
*
* @return string
*/
public function getDocumentClass()
{
return $this->getOption('documentclass');
} }
/** /**
* Set the number of rows to fetch * Set MLT fields option
* *
* @param integer $rows * The fields to use for similarity. NOTE: if possible, these should have a
* @return Solarium_Query_Select Provides fluent interface * stored TermVector
*/
public function setRows($rows)
{
return $this->_setOption('rows', $rows);
}
/**
* Get the number of rows
* *
* @return integer * Separate multiple fields with commas.
*/
public function getRows()
{
return $this->getOption('rows');
}
/**
* Specify a field to return in the resultset
* *
* @param string $field * @param string $fields
* @return Solarium_Query_Select Provides fluent interface * @return Solarium_Query_MoreLikeThis Provides fluent interface
*/ */
public function addField($field) public function setMltFields($fields)
{ {
$this->_fields[$field] = true; return $this->_setOption('mltfields', $fields);
return $this;
} }
/** /**
* Specify multiple fields to return in the resultset * Get MLT fields option
* *
* @param string|array $fields can be an array or string with comma * @return string|null
* separated fieldnames
*
* @return Solarium_Query_Select Provides fluent interface
*/ */
public function addFields($fields) public function getMltFields()
{ {
if (is_string($fields)) { return $this->getOption('mltfields');
$fields = explode(',', $fields);
$fields = array_map('trim', $fields);
}
foreach ($fields AS $field) {
$this->addField($field);
}
return $this;
} }
/** /**
* Remove a field from the field list * Set minimumtermfrequency option
* *
* @param string $field * Minimum Term Frequency - the frequency below which terms will be ignored
* @return Solarium_Query_Select Provides fluent interface * in the source doc.
*/
public function removeField($field)
{
if (isset($this->_fields[$field])) {
unset($this->_fields[$field]);
}
return $this;
}
/**
* Remove all fields from the field list.
* *
* @return Solarium_Query_Select Provides fluent interface * @param int $minimum
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/ */
public function clearFields() public function setMinimumTermFrequency($minimum)
{ {
$this->_fields = array(); return $this->_setOption('minimumtermfrequency', $minimum);
return $this;
} }
/** /**
* Get the list of fields * Get minimumtermfrequency option
* *
* @return array * @return integer|null
*/ */
public function getFields() public function getMinimumTermFrequency()
{ {
return array_keys($this->_fields); return $this->getOption('minimumtermfrequency');
} }
/** /**
* Set multiple fields * Set minimumdocumentfrequency option
* *
* This overwrites any existing fields * Minimum Document Frequency - the frequency at which words will be
* ignored which do not occur in at least this many docs.
* *
* @param array $fields * @param int $minimum
* @return Solarium_Query_Select Provides fluent interface * @return Solarium_Query_MoreLikeThis Provides fluent interface
*/ */
public function setFields($fields) public function setMinimumDocumentFrequency($minimum)
{ {
$this->clearFields(); return $this->_setOption('minimumdocumentfrequency', $minimum);
$this->addFields($fields);
return $this;
} }
/** /**
* Create a filterquery instance * Get minimumdocumentfrequency option
* *
* @param mixed $options * @return integer|null
* @return Solarium_Query_Select_FilterQuery
*/ */
public function createFilterQuery($options = null) public function getMinimumDocumentFrequency()
{ {
return new Solarium_Query_Select_FilterQuery($options); return $this->getOption('minimumdocumentfrequency');
} }
/** /**
* Add a filter query * Set minimumwordlength option
*
* Supports a filterquery instance or a config array, in that case a new
* filterquery instance wil be created based on the options.
* *
* @param Solarium_Query_Select_FilterQuery|array $filterQuery * Minimum word length below which words will be ignored.
* @return Solarium_Query_Select Provides fluent interface
*/
public function addFilterQuery($filterQuery)
{
if (is_array($filterQuery)) {
$filterQuery = new Solarium_Query_Select_FilterQuery($filterQuery);
}
$key = $filterQuery->getKey();
if (0 === strlen($key)) {
throw new Solarium_Exception('A filterquery must have a key value');
}
if (array_key_exists($key, $this->_filterQueries)) {
throw new Solarium_Exception('A filterquery must have a unique key'
. ' value within a query');
}
$this->_filterQueries[$key] = $filterQuery;
return $this;
}
/**
* Add multiple filterqueries
* *
* @param array $filterQueries * @param int $minimum
* @return Solarium_Query_Select Provides fluent interface * @return Solarium_Query_MoreLikeThis Provides fluent interface
*/ */
public function addFilterQueries(array $filterQueries) public function setMinimumWordLength($minimum)
{ {
foreach ($filterQueries AS $key => $filterQuery) { return $this->_setOption('minimumwordlength', $minimum);
// in case of a config array: add key to config
if (is_array($filterQuery) && !isset($filterQuery['key'])) {
$filterQuery['key'] = $key;
}
$this->addFilterQuery($filterQuery);
}
return $this;
} }
/** /**
* Get a filterquery * Get minimumwordlength option
* *
* @param string $key * @return integer|null
* @return string
*/ */
public function getFilterQuery($key) public function getMinimumWordLength()
{ {
if (isset($this->_filterQueries[$key])) { return $this->getOption('minimumwordlength');
return $this->_filterQueries[$key];
} else {
return null;
}
} }
/** /**
* Get all filterqueries * Set maximumwordlength option
* *
* @return array * Maximum word length above which words will be ignored.
*/
public function getFilterQueries()
{
return $this->_filterQueries;
}
/**
* Remove a single filterquery by key
* *
* @param string $key * @param int $maximum
* @return Solarium_Query_Select Provides fluent interface * @return Solarium_Query_MoreLikeThis Provides fluent interface
*/ */
public function removeFilterQuery($key) public function setMaximumWordLength($maximum)
{ {
if (isset($this->_filterQueries[$key])) { return $this->_setOption('maximumwordlength', $maximum);
unset($this->_filterQueries[$key]);
}
return $this;
} }
/** /**
* Remove all filterqueries * Get maximumwordlength option
* *
* @return Solarium_Query_Select Provides fluent interface * @return integer|null
*/ */
public function clearFilterQueries() public function getMaximumWordLength()
{ {
$this->_filterQueries = array(); return $this->getOption('maximumwordlength');
return $this;
} }
/** /**
* Set multiple filterqueries * Set maximumqueryterms option
* *
* This overwrites any existing filterqueries * Maximum number of query terms that will be included in any generated
* query.
* *
* @param array $filterQueries * @param int $maximum
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/ */
public function setFilterQueries($filterQueries) public function setMaximumQueryTerms($maximum)
{ {
$this->clearFilterQueries(); return $this->_setOption('maximumqueryterms', $maximum);
$this->addFilterQueries($filterQueries);
} }
/** /**
* Get all registered component types * Get maximumqueryterms option
* *
* @return array * @return integer|null
*/ */
public function getComponentTypes() public function getMaximumQueryTerms()
{ {
return $this->_componentTypes; return $this->getOption('maximumqueryterms');
} }
/** /**
* Register a component type * Set maximumnumberoftokens option
* *
* @param string $key * Maximum number of tokens to parse in each example doc field that is not
* @param string $component * stored with TermVector support.
* @param string $requestBuilder
* @param string $responseParser
* @return Solarium_Query_Select Provides fluent interface
*/
public function registerComponentType($key, $component, $requestBuilder=null, $responseParser=null)
{
$this->_componentTypes[$key] = array(
'component' => $component,
'requestbuilder' => $requestBuilder,
'responseparser' => $responseParser,
);
return $this;
}
/**
* Get all registered components
*
* @return array
*/
public function getComponents()
{
return $this->_components;
}
/**
* Get a component instance by key
* *
* You can optionally supply an autoload class to create a new component * @param int $maximum
* instance if there is no registered component for the given key yet. * @return Solarium_Query_MoreLikeThis Provides fluent interface
*
* @param string $key Use one of the constants
* @param string $autoload Class to autoload if component needs to be created
* @param array $config Configuration to use for autoload
* @return object|null
*/ */
public function getComponent($key, $autoload = false, $config = null) public function setMaximumNumberOfTokens($maximum)
{ {
if (isset($this->_components[$key])) { return $this->_setOption('maximumnumberoftokens', $maximum);
return $this->_components[$key];
} else {
if ($autoload == true) {
if (!isset($this->_componentTypes[$key])) {
throw new Solarium_Exception('Cannot autoload unknown component: ' . $key);
}
$className = $this->_componentTypes[$key]['component'];
$component = new $className($config);
$this->setComponent($key, $component);
return $component;
}
return null;
}
} }
/** /**
* Set a component instance * Get maximumnumberoftokens option
* *
* This overwrites any existing component registered with the same key. * @return integer|null
*
* @param string $key
* @param object|null $value
* @return Solarium_Query_Select Provides fluent interface
*/ */
public function setComponent($key, $value) public function getMaximumNumberOfTokens()
{ {
$this->_components[$key] = $value; return $this->getOption('maximumnumberoftokens');
return $this;
} }
/** /**
* Remove a component instance * Set boost option
* *
* @param string $key * If true the query will be boosted by the interesting term relevance.
* @return Solarium_Query_Select Provides fluent interface
*/
public function removeComponent($key)
{
if (isset($this->_components[$key])) {
unset($this->_components[$key]);
}
return $this;
}
/**
* Build component instances based on config
* *
* @param array $configs * @param boolean $boost
* @return void * @return Solarium_Query_MoreLikeThis Provides fluent interface
*/ */
protected function _createComponents($configs) public function setBoost($boost)
{ {
foreach ($configs AS $type => $config) { return $this->_setOption('boost', $boost);
$this->getComponent($type, true, $config);
}
} }
/** /**
* Get a MoreLikeThis component instance * Get boost option
*
* This is a convenience method that maps presets to getComponent
* *
* @return Solarium_Query_Select_Component_MoreLikeThis * @return boolean|null
*/ */
public function getMoreLikeThis() public function getBoost()
{ {
return $this->getComponent(Solarium_Query_Select::COMPONENT_MORELIKETHIS, true); return $this->getOption('boost');
} }
/** /**
* Get a FacetSet component instance * Set queryfields option
*
* This is a convenience method that maps presets to getComponent
* *
* @return Solarium_Query_Select_Component_FacetSet * Query fields and their boosts using the same format as that used in
*/ * DisMaxQParserPlugin. These fields must also be specified in fields.
public function getFacetSet()
{
return $this->getComponent(Solarium_Query_Select::COMPONENT_FACETSET, true);
}
/**
* Get a DisMax component instance
* *
* This is a convenience method that maps presets to getComponent * Separate multiple fields with commas.
* *
* @return Solarium_Query_Select_Component_DisMax * @param string $queryFields
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/ */
public function getDisMax() public function setQueryFields($queryFields)
{ {
return $this->getComponent(Solarium_Query_Select::COMPONENT_DISMAX, true); return $this->_setOption('queryfields', $queryFields);
} }
/** /**
* Get a highlighting component instance * Get queryfields option
*
* This is a convenience method that maps presets to getComponent
* *
* @return Solarium_Query_Select_Component_Highlighting * @return string|null
*/ */
public function getHighlighting() public function getQueryFields()
{ {
return $this->getComponent(Solarium_Query_Select::COMPONENT_HIGHLIGHTING, true); return $this->getOption('queryfields');
} }
} }
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