source: sandbox/expresso-solr/expressoMail1_2/solrclient/library/Solarium/Client.php @ 7588

Revision 7588, 24.2 KB checked in by adir, 11 years ago (diff)

Ticket #000 - Adicionando a integracao de buscas com Solr na base a ser isnerida na comunidade

Line 
1<?php
2/**
3 * Copyright 2011 Bas de Nooijer. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 *    this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 *    this listof conditions and the following disclaimer in the documentation
13 *    and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The views and conclusions contained in the software and documentation are
28 * those of the authors and should not be interpreted as representing official
29 * policies, either expressed or implied, of the copyright holder.
30 *
31 * @copyright Copyright 2011 Bas de Nooijer <solarium@raspberry.nl>
32 * @license http://github.com/basdenooijer/solarium/raw/master/COPYING
33 * @link http://www.solarium-project.org/
34 *
35 * @package Solarium
36 * @subpackage Client
37 */
38
39/**
40 * Main interface for interaction with Solr
41 *
42 * The client is the main interface for usage of the Solarium library.
43 * You can use it to get query instances and to execute them.
44 * It also allows to register plugins and querytypes to customize Solarium.
45 * Finally, it also gives access to the adapter, which holds the Solr connection settings.
46 *
47 * Example usage with default settings:
48 * <code>
49 * $client = new Solarium_Client;
50 * $query = $client->createSelect();
51 * $result = $client->select($query);
52 * </code>
53 *
54 * @package Solarium
55 * @subpackage Client
56 */
57class Solarium_Client extends Solarium_Configurable
58{
59
60    /**
61     * Querytype select
62     */
63    const QUERYTYPE_SELECT = 'select';
64
65    /**
66     * Querytype update
67     */
68    const QUERYTYPE_UPDATE = 'update';
69
70    /**
71     * Querytype ping
72     */
73    const QUERYTYPE_PING = 'ping';
74
75    /**
76     * Querytype morelikethis
77     */
78    const QUERYTYPE_MORELIKETHIS = 'mlt';
79
80    /**
81     * Querytype analysis field
82     */
83    const QUERYTYPE_ANALYSIS_FIELD = 'analysis-field';
84
85    /**
86     * Querytype analysis document
87     */
88    const QUERYTYPE_ANALYSIS_DOCUMENT = 'analysis-document';
89
90    /**
91     * Querytype terms
92     */
93    const QUERYTYPE_TERMS = 'terms';
94
95    /**
96     * Querytype suggester
97     */
98    const QUERYTYPE_SUGGESTER = 'suggester';
99
100    /**
101     * Default options
102     *
103     * @var array
104     */
105    protected $_options = array(
106        'adapter' => 'Solarium_Client_Adapter_Http',
107    );
108
109    /**
110     * Querytype mappings
111     *
112     * These can be customized using {@link registerQueryType()}
113     */
114    protected $_queryTypes = array(
115        self::QUERYTYPE_SELECT => array(
116            'query'          => 'Solarium_Query_Select',
117            'requestbuilder' => 'Solarium_Client_RequestBuilder_Select',
118            'responseparser' => 'Solarium_Client_ResponseParser_Select'
119        ),
120        self::QUERYTYPE_UPDATE => array(
121            'query'          => 'Solarium_Query_Update',
122            'requestbuilder' => 'Solarium_Client_RequestBuilder_Update',
123            'responseparser' => 'Solarium_Client_ResponseParser_Update'
124        ),
125        self::QUERYTYPE_PING => array(
126            'query'          => 'Solarium_Query_Ping',
127            'requestbuilder' => 'Solarium_Client_RequestBuilder_Ping',
128            'responseparser' => 'Solarium_Client_ResponseParser_Ping'
129        ),
130        self::QUERYTYPE_MORELIKETHIS => array(
131            'query'           => 'Solarium_Query_MoreLikeThis',
132            'requestbuilder'  => 'Solarium_Client_RequestBuilder_MoreLikeThis',
133            'responseparser'  => 'Solarium_Client_ResponseParser_MoreLikeThis'
134        ),
135        self::QUERYTYPE_ANALYSIS_DOCUMENT => array(
136            'query'          => 'Solarium_Query_Analysis_Document',
137            'requestbuilder' => 'Solarium_Client_RequestBuilder_Analysis_Document',
138            'responseparser' => 'Solarium_Client_ResponseParser_Analysis_Document'
139        ),
140        self::QUERYTYPE_ANALYSIS_FIELD => array(
141            'query'          => 'Solarium_Query_Analysis_Field',
142            'requestbuilder' => 'Solarium_Client_RequestBuilder_Analysis_Field',
143            'responseparser' => 'Solarium_Client_ResponseParser_Analysis_Field'
144        ),
145        self::QUERYTYPE_TERMS => array(
146            'query'          => 'Solarium_Query_Terms',
147            'requestbuilder' => 'Solarium_Client_RequestBuilder_Terms',
148            'responseparser' => 'Solarium_Client_ResponseParser_Terms'
149        ),
150        self::QUERYTYPE_SUGGESTER => array(
151            'query'          => 'Solarium_Query_Suggester',
152            'requestbuilder' => 'Solarium_Client_RequestBuilder_Suggester',
153            'responseparser' => 'Solarium_Client_ResponseParser_Suggester'
154        ),
155    );
156
157    /**
158     * Plugin types
159     *
160     * @var array
161     */
162    protected $_pluginTypes = array(
163        'loadbalancer' => 'Solarium_Plugin_Loadbalancer',
164        'postbigrequest' => 'Solarium_Plugin_PostBigRequest',
165        'customizerequest' => 'Solarium_Plugin_CustomizeRequest',
166        'parallelexecution' => 'Solarium_Plugin_ParallelExecution',
167        'bufferedadd' => 'Solarium_Plugin_BufferedAdd',
168        'prefetchiterator' => 'Solarium_Plugin_PrefetchIterator',
169    );
170
171    /**
172     * Registered plugin instances
173     *
174     * @var array
175     */
176    protected $_pluginInstances = array();
177
178    /**
179     * Adapter instance
180     *
181     * If an adapter instance is set using {@link setAdapter()} this var will
182     * contain a reference to that instance.
183     *
184     * In all other cases the adapter is lazy-loading, it will be instantiated
185     * on first use by {@link getAdapter()} based on the 'adapter' entry in
186     * {@link $_options}. This option can be set using {@link setAdapter()}
187     *
188     * @var Solarium_Client_Adapter
189     */
190    protected $_adapter;
191
192    /**
193     * Request builder instances
194     *
195     * @var array
196     */
197    protected $_requestBuilders;
198
199    /**
200     * Initialization hook
201     */
202    protected function _init()
203    {
204        foreach ($this->_options AS $name => $value) {
205            switch ($name) {
206                case 'querytype':
207                    $this->registerQueryTypes($value);
208                    break;
209                case 'plugin':
210                    $this->registerPlugins($value);
211                    break;
212            }
213        }
214    }
215
216    /**
217     * Set the adapter
218     *
219     * The adapter has to be a class that extends
220     * {@link Solarium_Client_Adapter}.
221     *
222     * If a string is passed it is assumed to be the classname and it will be
223     * instantiated on first use. This requires the availability of the class
224     * through autoloading or a manual require before calling this method.
225     * Any existing adapter instance will be removed by this method, this way an
226     * instance of the new adapter type will be created upon the next usage of
227     * the adapter (lazy-loading)
228     *
229     * If an adapter instance is passed it will replace the current adapter
230     * immediately, bypassing the lazy loading.
231     *
232     * @param string|Solarium_Client_Adapter $adapter
233     * @return Solarium_Client Provides fluent interface
234     */
235    public function setAdapter($adapter)
236    {
237        if (is_string($adapter)) {
238            $this->_adapter = null;
239            return $this->_setOption('adapter', $adapter);
240        } else {
241            // forward options
242            $adapter->setOptions($this->_options);
243            // overwrite existing adapter
244            $this->_adapter = $adapter;
245            return $this;
246        }
247    }
248
249    /**
250     * Create an adapter instance
251     *
252     * The 'adapter' entry in {@link $_options} will be used to create an
253     * adapter instance. This entry can be the default value of
254     * {@link $_options}, a value passed to the constructor or a value set by
255     * using {@link setAdapter()}
256     *
257     * This method is used for lazy-loading the adapter upon first use in
258     * {@link getAdapter()}
259     *
260     * @return void
261     */
262    protected function _createAdapter()
263    {
264        $adapterClass = $this->getOption('adapter');
265        $this->_adapter = new $adapterClass;
266        $this->_adapter->setOptions($this->getOption('adapteroptions'));
267    }
268
269    /**
270     * Get the adapter instance
271     *
272     * If {@see $_adapter} doesn't hold an instance a new one will be created by
273     * calling {@see _createAdapter()}
274     *
275     * @param boolean $autoload
276     * @return Solarium_Client_Adapter
277     */
278    public function getAdapter($autoload = true)
279    {
280        if (null === $this->_adapter && $autoload) {
281            $this->_createAdapter();
282        }
283
284        return $this->_adapter;
285    }
286
287    /**
288     * Register a querytype
289     *
290     * You can also use this method to override any existing querytype with a new mapping.
291     * This requires the availability of the classes through autoloading or a manual
292     * require before calling this method.
293     *
294     * @param string $type
295     * @param string $query
296     * @param string|object $requestBuilder
297     * @param string|object $responseParser
298     * @return Solarium_Client Provides fluent interface
299     */
300    public function registerQueryType($type, $query, $requestBuilder, $responseParser)
301    {
302        $this->_queryTypes[$type] = array(
303            'query' => $query,
304            'requestbuilder' => $requestBuilder,
305            'responseparser' => $responseParser,
306        );
307
308        return $this;
309    }
310
311    /**
312     * Register multiple querytypes
313     *
314     * @param array $queryTypes
315     * @return Solarium_Client Provides fluent interface
316     */
317    public function registerQueryTypes($queryTypes)
318    {
319        foreach ($queryTypes as $type => $queryType) {
320
321            if (!isset($queryType['type'])) $queryType['type'] = $type;
322
323            $this->registerQueryType(
324                $queryType['type'],
325                $queryType['query'],
326                $queryType['requestbuilder'],
327                $queryType['responseparser']
328            );
329        }
330    }
331
332    /**
333     * Get all registered querytypes
334     *
335     * @return array
336     */
337    public function getQueryTypes()
338    {
339        return $this->_queryTypes;
340    }
341
342    /**
343     * Register a plugin
344     *
345     * You can supply a plugin instance or a plugin classname as string.
346     * This requires the availability of the class through autoloading
347     * or a manual require.
348     *
349     * @param string $key
350     * @param string|Solarium_Plugin_Abstract $plugin
351     * @param array $options
352     * @return Solarium_Client Provides fluent interface
353     */
354    public function registerPlugin($key, $plugin, $options = array())
355    {
356        if (is_string($plugin)) {
357            $plugin = new $plugin;
358        }
359
360        if (!($plugin instanceof Solarium_Plugin_Abstract)) {
361           throw new Solarium_Exception('All plugins must extend Solarium_Plugin_Abstract');
362        }
363
364        $plugin->init($this, $options);
365
366        $this->_pluginInstances[$key] = $plugin;
367
368        return $this;
369    }
370
371    /**
372     * Register multiple plugins
373     *
374     * @param array $plugins
375     * @return Solarium_Client Provides fluent interface
376     */
377    public function registerPlugins($plugins)
378    {
379        foreach ($plugins as $key => $plugin) {
380
381            if (!isset($plugin['key'])) $plugin['key'] = $key;
382
383            $this->registerPlugin(
384                $plugin['key'],
385                $plugin['plugin'],
386                $plugin['options']
387            );
388        }
389
390        return $this;
391    }
392
393    /**
394     * Get all registered plugins
395     *
396     * @return array
397     */
398    public function getPlugins()
399    {
400        return $this->_pluginInstances;
401    }
402
403    /**
404     * Get a plugin instance
405     *
406     * @param string $key
407     * @param boolean $autocreate
408     * @return Solarium_Plugin_Abstract|null
409     */
410    public function getPlugin($key, $autocreate = true)
411    {
412        if (isset($this->_pluginInstances[$key])) {
413            return $this->_pluginInstances[$key];
414        } elseif ($autocreate) {
415            if (array_key_exists($key, $this->_pluginTypes)) {
416                $this->registerPlugin($key, $this->_pluginTypes[$key]);
417                return $this->_pluginInstances[$key];
418            } else {
419                throw new Solarium_Exception('Cannot autoload plugin of unknown type: ' . $key);
420            }
421        } else {
422            return null;
423        }
424    }
425
426    /**
427     * Remove a plugin instance
428     *
429     * You can remove a plugin by passing the plugin key, or the plugin instance
430     *
431     * @param string|Solarium_Plugin_Abstract $plugin
432     * @return Solarium_Client Provides fluent interface
433     */
434    public function removePlugin($plugin)
435    {
436        if (is_object($plugin)) {
437            foreach ($this->_pluginInstances as $key => $instance) {
438                if ($instance === $plugin) {
439                    unset($this->_pluginInstances[$key]);
440                    break;
441                }
442            }
443        } else {
444            if (isset($this->_pluginInstances[$plugin])) {
445                unset($this->_pluginInstances[$plugin]);
446            }
447        }
448        return $this;
449    }
450
451    /**
452     * Trigger external events for plugins
453     *
454     * This methods adds 'namespacing' to the event name to prevent conflicts with Solariums internal event keys.
455     *
456     * Based on the event name you can always tell if an event was internal (Solarium base classes)
457     * or external (plugins, even if it's a plugin included with Solarium).
458     *
459     * External events always have the 'event' prefix in the event name.
460     *
461     * @param string $event
462     * @param array $params
463     * @param bool $resultOverride
464     * @return void|mixed
465     */
466    public function triggerEvent($event, $params = array(), $resultOverride = false)
467    {
468        // Add namespacing
469        $event = 'event'.$event;
470
471        return $this->_callPlugins($event, $params, $resultOverride);
472    }
473
474    /**
475     * Forward events to plugins
476     *
477     * @param string $event
478     * @param array $params
479     * @param bool $resultOverride
480     * @return void|mixed
481     */
482    protected function _callPlugins($event, $params, $resultOverride = false)
483    {
484        foreach ($this->_pluginInstances AS $plugin) {
485            if (method_exists($plugin, $event)) {
486                $result = call_user_func_array(array($plugin, $event), $params);
487
488                if ($result !== null && $resultOverride) {
489                    return $result;
490                }
491            }
492        }
493    }
494
495    /**
496     * Creates a request based on a query instance
497     *
498     * @param Solarium_Query $query
499     * @return Solarium_Client_Request
500     */
501    public function createRequest($query)
502    {
503        $pluginResult = $this->_callPlugins('preCreateRequest', array($query), true);
504        if($pluginResult !== null) return $pluginResult;
505
506        $queryType = $query->getType();
507        if (!isset($this->_queryTypes[$queryType])) {
508            throw new Solarium_Exception('No requestbuilder registered for querytype: '. $queryType);
509        }
510
511        $requestBuilder = $this->_queryTypes[$queryType]['requestbuilder'];
512        if (is_string($requestBuilder)) {
513            $requestBuilder = new $requestBuilder;
514        }
515        $request = $requestBuilder->build($query);
516
517        $this->_callPlugins('postCreateRequest', array($query, $request));
518
519        return $request;
520    }
521
522    /**
523     * Creates a result object
524     *
525     * @param Solarium_Query $query
526     * @param array Solarium_Client_Response $response
527     * @return Solarium_Result
528     */
529    public function createResult($query, $response)
530    {
531        $pluginResult = $this->_callPlugins('preCreateResult', array($query, $response), true);
532        if($pluginResult !== null) return $pluginResult;
533
534        $resultClass = $query->getResultClass();
535        $result = new $resultClass($this, $query, $response);
536
537        $this->_callPlugins('postCreateResult', array($query, $response, $result));
538
539        return $result;
540    }
541
542    /**
543     * Execute a query
544     *
545     * @param Solarium_Query
546     * @return Solarium_Result
547     */
548    public function execute($query)
549    {
550        $pluginResult = $this->_callPlugins('preExecute', array($query), true);
551        if($pluginResult !== null) return $pluginResult;
552
553        $request = $this->createRequest($query);
554        $response = $this->executeRequest($request);
555        $result = $this->createResult($query, $response);
556
557        $this->_callPlugins('postExecute', array($query, $result));
558
559        return $result;
560    }
561
562    /**
563     * Execute a request and return the response
564     *
565     * @param Solarium_Client_Request
566     * @return Solarium_Client_Response
567     */
568    public function executeRequest($request)
569    {
570        $pluginResult = $this->_callPlugins('preExecuteRequest', array($request), true);
571        if ($pluginResult !== null) {
572            $response = $pluginResult; //a plugin result overrules the standard execution result
573        } else {
574            $response = $this->getAdapter()->execute($request);
575        }
576
577        $this->_callPlugins('postExecuteRequest', array($request, $response));
578
579        return $response;
580    }
581
582    /**
583     * Execute a ping query
584     *
585     * Example usage:
586     * <code>
587     * $client = new Solarium_Client;
588     * $query = $client->createPing();
589     * $result = $client->ping($query);
590     * </code>
591     *
592     * @see Solarium_Query_Ping
593     *
594     * @internal This is a convenience method that forwards the query to the
595     *  execute method, thus allowing for an easy to use and clean API.
596     *
597     * @param Solarium_Query_Ping $query
598     * @return Solarium_Result_Ping
599     */
600    public function ping($query)
601    {
602        return $this->execute($query);
603    }
604
605    /**
606     * Execute an update query
607     *
608     * Example usage:
609     * <code>
610     * $client = new Solarium_Client;
611     * $query = $client->createUpdate();
612     * $update->addOptimize();
613     * $result = $client->update($update);
614     * </code>
615     *
616     * @see Solarium_Query_Update
617     * @see Solarium_Result_Update
618     *
619     * @internal This is a convenience method that forwards the query to the
620     *  execute method, thus allowing for an easy to use and clean API.
621     *
622     * @param Solarium_Query_Update $query
623     * @return Solarium_Result_Update
624     */
625    public function update($query)
626    {
627        return $this->execute($query);
628    }
629
630    /**
631     * Execute a select query
632     *
633     * Example usage:
634     * <code>
635     * $client = new Solarium_Client;
636     * $query = $client->createSelect();
637     * $result = $client->select($query);
638     * </code>
639     *
640     * @see Solarium_Query_Select
641     * @see Solarium_Result_Select
642     *
643     * @internal This is a convenience method that forwards the query to the
644     *  execute method, thus allowing for an easy to use and clean API.
645     *
646     * @param Solarium_Query_Select $query
647     * @return Solarium_Result_Select
648     */
649    public function select($query)
650    {
651        return $this->execute($query);
652    }
653
654    /**
655     * Execute a MoreLikeThis query
656     *
657     * Example usage:
658     * <code>
659     * $client = new Solarium_Client;
660     * $query = $client->createMoreLikeThis();
661     * $result = $client->moreLikeThis($query);
662     * </code>
663     *
664     * @see Solarium_Query_MoreLikeThis
665     * @see Solarium_Result_MoreLikeThis
666     *
667     * @internal This is a convenience method that forwards the query to the
668     *  execute method, thus allowing for an easy to use and clean API.
669     *
670     * @param Solarium_Query_MoreLikeThis $query
671     * @return Solarium_Result_MoreLikeThis
672     */
673    public function moreLikeThis($query)
674    {
675        return $this->execute($query);
676    }
677
678    /**
679     * Execute an analysis query
680     *
681     * @internal This is a convenience method that forwards the query to the
682     *  execute method, thus allowing for an easy to use and clean API.
683     *
684     * @param Solarium_Query_Analysis_Document|Solarium_Query_Analysis_Field $query
685     * @return Solarium_Result_Analysis_Document|Solarium_Result_Analysis_Field
686     */
687    public function analyze($query)
688    {
689        return $this->execute($query);
690    }
691
692    /**
693     * Execute a terms query
694     *
695     * @internal This is a convenience method that forwards the query to the
696     *  execute method, thus allowing for an easy to use and clean API.
697     *
698     * @param Solarium_Query_Terms $query
699     * @return Solarium_Result_Terms
700     */
701    public function terms($query)
702    {
703        return $this->execute($query);
704    }
705
706    /**
707     * Execute a suggester query
708     *
709     * @internal This is a convenience method that forwards the query to the
710     *  execute method, thus allowing for an easy to use and clean API.
711     *
712     * @param Solarium_Query_Suggester $query
713     * @return Solarium_Result_Suggester
714     */
715    public function suggester($query)
716    {
717        return $this->execute($query);
718    }
719
720    /**
721     * Create a query instance
722     *
723     * @param string $type
724     * @param array $options
725     * @return Solarium_Query
726     */
727    public function createQuery($type, $options = null)
728    {
729        $type = strtolower($type);
730
731        $pluginResult = $this->_callPlugins('preCreateQuery', array($type, $options), true);
732        if($pluginResult !== null) return $pluginResult;
733
734        if (!isset($this->_queryTypes[$type])) {
735            throw new Solarium_Exception('Unknown querytype: '. $type);
736        }
737
738        $class = $this->_queryTypes[$type]['query'];
739        $query = new $class($options);
740
741        $this->_callPlugins('postCreateQuery', array($type, $options, $query));
742
743        return $query;
744    }
745
746    /**
747     * Create a select query instance
748     *
749     * @param mixed $options
750     * @return Solarium_Query_Select
751     */
752    public function createSelect($options = null)
753    {
754        return $this->createQuery(self::QUERYTYPE_SELECT, $options);
755    }
756
757    /**
758     * Create a MoreLikeThis query instance
759     *
760     * @param mixed $options
761     * @return Solarium_Query_MoreLikeThis
762     */
763    public function createMoreLikeThis($options = null)
764    {
765        return $this->createQuery(self::QUERYTYPE_MORELIKETHIS, $options);
766    }
767
768    /**
769     * Create an update query instance
770     *
771     * @param mixed $options
772     * @return Solarium_Query_Update
773     */
774    public function createUpdate($options = null)
775    {
776        return $this->createQuery(self::QUERYTYPE_UPDATE, $options);
777    }
778
779    /**
780     * Create a ping query instance
781     *
782     * @param mixed $options
783     * @return Solarium_Query_Ping
784     */
785    public function createPing($options = null)
786    {
787        return $this->createQuery(self::QUERYTYPE_PING, $options);
788    }
789
790    /**
791     * Create an analysis field query instance
792     *
793     * @param mixed $options
794     * @return Solarium_Query_Analysis_Field
795     */
796    public function createAnalysisField($options = null)
797    {
798        return $this->createQuery(self::QUERYTYPE_ANALYSIS_FIELD, $options);
799    }
800
801    /**
802     * Create an analysis document query instance
803     *
804     * @param mixed $options
805     * @return Solarium_Query_Analysis_Document
806     */
807    public function createAnalysisDocument($options = null)
808    {
809        return $this->createQuery(self::QUERYTYPE_ANALYSIS_DOCUMENT, $options);
810    }
811
812    /**
813     * Create a terms query instance
814     *
815     * @param mixed $options
816     * @return Solarium_Query_Terms
817     */
818    public function createTerms($options = null)
819    {
820        return $this->createQuery(self::QUERYTYPE_TERMS, $options);
821    }
822
823    /**
824     * Create a suggester query instance
825     *
826     * @param mixed $options
827     * @return Solarium_Query_Suggester
828     */
829    public function createSuggester($options = null)
830    {
831        return $this->createQuery(self::QUERYTYPE_SUGGESTER, $options);
832    }
833}
Note: See TracBrowser for help on using the repository browser.