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 @@
* @package Solarium
* @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
*
......@@ -89,149 +74,37 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query
'query' => '*:*',
'start' => 0,
'rows' => 10,
'fl' => '*,score',
'mlt.fl' => 'text',
'mlt.interestingTerms' => 'none',
'mlt.match.include' => 'false',
'fields' => '*,score',
'interestingTerms' => 'none',
'matchinclude' => false,
'stream' => false
);
/**
* Default select query component types
*
* @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
*/
protected $_fields = array();
/**
* Filterqueries
*
* @var array
*/
protected $_filterQueries = array();
/**
* Search components
* Set query stream option
*
* @var array
*/
protected $_components = array();
/**
* Initialize options
* Set to true to post query content instead of using the URL param
*
* Several options need some extra checks or setup work, for these options
* the setters are called.
* @link http://wiki.apache.org/solr/ContentStream ContentStream
*
* @return void
* @param boolean $stream
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/
protected function _init()
public function setQueryStream($stream)
{
foreach ($this->_options AS $name => $value) {
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;
}
}
return $this->_setOption('stream', $stream);
}
/**
* Set the query string
*
* Overwrites the current value. You are responsible for the correct
* escaping of user input.
* Get stream option
*
* @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
*/
public function isStream()
public function getQueryStream()
{
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.
*
......@@ -241,7 +114,7 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query
*/
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
*/
public function getInterestingTerms()
{
return $this->getOption('mlt.interestingTerms');
return $this->getOption('interestingTerms');
}
/**
......@@ -262,7 +135,7 @@ class Solarium_Query_MoreLikeThis extends Solarium_Query
*/
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
*/
public function getMatchInclude()
{
return $this->getOption('mlt.match.include');
return $this->getOption('matchinclude');
}
/**
* Set a custom resultclass
* Set MLT fields option
*
* @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
*
* @param integer $rows
* @return Solarium_Query_Select Provides fluent interface
*/
public function setRows($rows)
{
return $this->_setOption('rows', $rows);
}
/**
* Get the number of rows
* The fields to use for similarity. NOTE: if possible, these should have a
* stored TermVector
*
* @return integer
*/
public function getRows()
{
return $this->getOption('rows');
}
/**
* Specify a field to return in the resultset
* Separate multiple fields with commas.
*
* @param string $field
* @return Solarium_Query_Select Provides fluent interface
* @param string $fields
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/
public function addField($field)
public function setMltFields($fields)
{
$this->_fields[$field] = true;
return $this;
return $this->_setOption('mltfields', $fields);
}
/**
* Specify multiple fields to return in the resultset
*
* @param string|array $fields can be an array or string with comma
* separated fieldnames
* Get MLT fields option
*
* @return Solarium_Query_Select Provides fluent interface
* @return string|null
*/
public function addFields($fields)
public function getMltFields()
{
if (is_string($fields)) {
$fields = explode(',', $fields);
$fields = array_map('trim', $fields);
}
foreach ($fields AS $field) {
$this->addField($field);
}
return $this;
return $this->getOption('mltfields');
}
/**
* Remove a field from the field list
* Set minimumtermfrequency option
*
* @param string $field
* @return Solarium_Query_Select Provides fluent interface
*/
public function removeField($field)
{
if (isset($this->_fields[$field])) {
unset($this->_fields[$field]);
}
return $this;
}
/**
* Remove all fields from the field list.
* Minimum Term Frequency - the frequency below which terms will be ignored
* in the source doc.
*
* @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;
return $this->_setOption('minimumtermfrequency', $minimum);
}
/**
* 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
*
* This overwrites any existing fields
* Set minimumdocumentfrequency option
*
* @param array $fields
* @return Solarium_Query_Select Provides fluent interface
*/
public function setFields($fields)
{
$this->clearFields();
$this->addFields($fields);
return $this;
}
/**
* Create a filterquery instance
* Minimum Document Frequency - the frequency at which words will be
* ignored which do not occur in at least this many docs.
*
* @param mixed $options
* @return Solarium_Query_Select_FilterQuery
* @param int $minimum
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/
public function createFilterQuery($options = null)
public function setMinimumDocumentFrequency($minimum)
{
return new Solarium_Query_Select_FilterQuery($options);
return $this->_setOption('minimumdocumentfrequency', $minimum);
}
/**
* Add a filter query
*
* Supports a filterquery instance or a config array, in that case a new
* filterquery instance wil be created based on the options.
* Get minimumdocumentfrequency option
*
* @param Solarium_Query_Select_FilterQuery|array $filterQuery
* @return Solarium_Query_Select Provides fluent interface
* @return integer|null
*/
public function addFilterQuery($filterQuery)
public function getMinimumDocumentFrequency()
{
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;
return $this->getOption('minimumdocumentfrequency');
}
/**
* Add multiple filterqueries
* Set minimumwordlength option
*
* @param array $filterQueries
* @return Solarium_Query_Select Provides fluent interface
*/
public function addFilterQueries(array $filterQueries)
{
foreach ($filterQueries AS $key => $filterQuery) {
// 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
* Minimum word length below which words will be ignored.
*
* @param string $key
* @return string
* @param int $minimum
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/
public function getFilterQuery($key)
public function setMinimumWordLength($minimum)
{
if (isset($this->_filterQueries[$key])) {
return $this->_filterQueries[$key];
} else {
return null;
}
return $this->_setOption('minimumwordlength', $minimum);
}
/**
* Get all filterqueries
* Get minimumwordlength option
*
* @return array
* @return integer|null
*/
public function getFilterQueries()
public function getMinimumWordLength()
{
return $this->_filterQueries;
return $this->getOption('minimumwordlength');
}
/**
* Remove a single filterquery by key
* Set maximumwordlength option
*
* @param string $key
* @return Solarium_Query_Select Provides fluent interface
*/
public function removeFilterQuery($key)
{
if (isset($this->_filterQueries[$key])) {
unset($this->_filterQueries[$key]);
}
return $this;
}
/**
* Remove all filterqueries
* Maximum word length above which words will be ignored.
*
* @return Solarium_Query_Select Provides fluent interface
* @param int $maximum
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/
public function clearFilterQueries()
public function setMaximumWordLength($maximum)
{
$this->_filterQueries = array();
return $this;
return $this->_setOption('maximumwordlength', $maximum);
}
/**
* Set multiple filterqueries
*
* This overwrites any existing filterqueries
* Get maximumwordlength option
*
* @param array $filterQueries
* @return integer|null
*/
public function setFilterQueries($filterQueries)
public function getMaximumWordLength()
{
$this->clearFilterQueries();
$this->addFilterQueries($filterQueries);
return $this->getOption('maximumwordlength');
}
/**
* Get all registered component types
* Set maximumqueryterms option
*
* @return array
*/
public function getComponentTypes()
{
return $this->_componentTypes;
}
/**
* Register a component type
* Maximum number of query terms that will be included in any generated
* query.
*
* @param string $key
* @param string $component
* @param string $requestBuilder
* @param string $responseParser
* @return Solarium_Query_Select Provides fluent interface
* @param int $maximum
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/
public function registerComponentType($key, $component, $requestBuilder=null, $responseParser=null)
public function setMaximumQueryTerms($maximum)
{
$this->_componentTypes[$key] = array(
'component' => $component,
'requestbuilder' => $requestBuilder,
'responseparser' => $responseParser,
);
return $this;
return $this->_setOption('maximumqueryterms', $maximum);
}
/**
* Get all registered components
* Get maximumqueryterms option
*
* @return array
* @return integer|null
*/
public function getComponents()
public function getMaximumQueryTerms()
{
return $this->_components;
return $this->getOption('maximumqueryterms');
}
/**
* Get a component instance by key
* Set maximumnumberoftokens option
*
* You can optionally supply an autoload class to create a new component
* instance if there is no registered component for the given key yet.
* Maximum number of tokens to parse in each example doc field that is not
* stored with TermVector support.
*
* @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
* @param int $maximum
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/
public function getComponent($key, $autoload = false, $config = null)
public function setMaximumNumberOfTokens($maximum)
{
if (isset($this->_components[$key])) {
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;
}
return $this->_setOption('maximumnumberoftokens', $maximum);
}
/**
* Set a component instance
* Get maximumnumberoftokens option
*
* This overwrites any existing component registered with the same key.
*
* @param string $key
* @param object|null $value
* @return Solarium_Query_Select Provides fluent interface
* @return integer|null
*/
public function setComponent($key, $value)
public function getMaximumNumberOfTokens()
{
$this->_components[$key] = $value;
return $this;
return $this->getOption('maximumnumberoftokens');
}
/**
* Remove a component instance
* Set boost option
*
* @param string $key
* @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
* If true the query will be boosted by the interesting term relevance.
*
* @param array $configs
* @return void
* @param boolean $boost
* @return Solarium_Query_MoreLikeThis Provides fluent interface
*/
protected function _createComponents($configs)
public function setBoost($boost)
{
foreach ($configs AS $type => $config) {
$this->getComponent($type, true, $config);
}
return $this->_setOption('boost', $boost);
}
/**
* Get a MoreLikeThis component instance
*
* This is a convenience method that maps presets to getComponent
* Get boost option
*
* @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
* Query fields and their boosts using the same format as that used in
* DisMaxQParserPlugin. These fields must also be specified in fields.
*
* @return Solarium_Query_Select_Component_FacetSet
*/
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
*
* This is a convenience method that maps presets to getComponent
* Get queryfields option
*
* @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