DGSphinxSearch Extension ¶
DoubleGIS company presents Yii extensions for SphinxClient library.
The 'DGSphinxSearch' is a Yii Framework Plugin that provides a Wrapper for SphinxClient interface. Contains all methods of SphinxClient for full text searching and usefull SQL-like interface.
Sphinx is an open source full text search server, designed from the ground up with performance, relevance (aka search quality), and integration simplicity in mind. It's written in C++ and works on Linux (RedHat, Ubuntu, etc), Windows, MacOS, Solaris, FreeBSD, and a few other systems.
Changelog ¶
1.1
- SPH_MATCH_FULLSCAN support added.
- SPH_RANK_TOTAL support added
- Some bugs fixed
1.0
- Initial release
Requirements ¶
- Yii 1.1.*
- Sphinx Client PECL extension (http://pecl.php.net/package/sphinx)
Installation ¶
- Unpack all files under your project 'component' folder
- Include your new exteniosn into your project main.php configuration file:
'components' => array(
...
'search' => array(
'class' => 'application.components.DGSphinxSearch',
'server' => '127.0.0.1',
'port' => 9312,
'maxQueryTime' => 3000,
'enableProfiling'=>0,
'enableResultTrace'=>0,
'fieldWeights' => array(
'name' => 10000,
'keywords' => 100,
),
),
...
)
- Enjoy!
Usage ¶
Search by criteria Object:
$searchCriteria = new stdClass();
$pages = new CPagination();
$pages->pageSize = Yii::app()->params['firmPerPage'];
$searchCriteria->select = 'project_id';
$searchCriteria->filters = array('project_id' => $project_id);
$searchCriteria->query = '@name '.$query.'*';
$searchCriteria->paginator = $pages;
$searchCriteria->groupby = $groupby;
$searchCriteria->orders = array('f_name' => 'ASC');
$searchCriteria->from = 'firm';
$resIterator = Yii::App()->search->search($searchCriteria); // interator result
/* OR */
$resArray = Yii::App()->search->searchRaw($searchCriteria); // array result
Search by SQL-like syntax:
$search->select('*')->
from($indexName)->
where($expression)->
filters(array('project_id' => $this->_city->id))->
groupby($groupby)->
orderby(array('f_name' => 'ASC'))->
limit(0, 30);
$resIterator = $search->search(); // interator result
/* OR */
$resArray = $search->searchRaw(); // array result
Search by SphinxClient syntax:
$search = Yii::App()->search;
$search->setSelect('*');
$search->setArrayResult(false);
$search->setMatchMode(SPH_MATCH_EXTENDED);
$search->setFieldWeights($fieldWeights)
$resArray = $search->query( $query, $indexName);
Combined Method:
$search = Yii::App()->search->
setArrayResult(false)->
setMatchMode(SPH_MATCH_EXTENDED);
$resIterator = $search->select('field_1, field_2')->search($searchCriteria);
Nice
This is very nice. Do you think it could be made to return active record objects also?
Returning AR objects is somewhat totally different from what Sphinx does.
Nice work though!
Guide
Is there a guide to set up the server and populate it with data or is somebody planning to write any? I would very much appreciate a thorough guide to a Yii programmer (from downloading sphinx to using the extension), as this is my first time implementing a search server. I think it could become an useful resource to new Yii programmers.
Thanks.
I second that motion - Thomas Jensen
That would be super handy
And I third the motion
A Guide would be most welcome
Guide
There is a book by Packt Pub called Sphinx Search Beginner's Guide
I have been following this book, and this seems like the guide people (including me) were asking for here.
Update
Is there a chance for new version in the future?
The extension is very nice, but with AR obj will be really useful.
:)
Limits
$this->client->setLimits(0, 1000000, 2000);
This should have an option. Default sphinx configuration has "max_matches" set to 1000.
Nice extension but have a question
First of all can you clearly explain if the example given go in action controller or somewhere else. Also do I need to index sphinx first before use.
Old dependency
Sphinx Client PECL extension is relative old ("Added support for new API in sphinx 1.10"), some class methods and predefined constants don't exists (e.g. SPH_RANK_SPH04). If you install it, dgsphinxsearch will use it.
Nice extension
Thx for comfortable work with sphinx in Yii
Misprint here:
Include your new exteniosn into your project main.php configuration file:
exclude
I some modify function for using "exclude". May be it was usefully.
public function filters($filters) { $this->criteria->filters = $filters; //set filters if ($filters && is_array($filters)) { foreach ($filters as $fil => $vol) { // geo filter if ($fil == 'geo') { $min = (float) (isset($vol['min']) ? $vol['min'] : 0); $point = explode(' ', str_replace('POINT(', '', trim($vol['point'], ')'))); $this->client->setGeoAnchor('latitude', 'longitude', (float) $point[1] * ( pi() / 180 ), (float) $point[0] * ( pi() / 180 )); $this->client->setFilterFloatRange('@geodist', $min, (float) $vol['buffer']); } else if ($vol) { $exclude = false; if(is_array($vol) && isset($vol['exclude'])) { $exclude = (bool) $vol['exclude']; unset($vol['exclude']); } $this->client->SetFilter($fil, (is_array($vol)) ? $vol : array($vol), $exclude); } } } return $this; }
Another extension
Another better extension: https://github.com/mitallast/yii-sphinx
Bug report
This code:
$searchCriteria->orders=array('base_type'=>'ASC');
Gives following error:
Argument 1 passed to DGSphinxSearch::orderby() must be an instance of DGSort, array given
FilterRange
hi all,
this is my filter function:
public function filters($filters) { $this->criteria->filters = $filters; //set filters if ($filters && is_array($filters)) { foreach ($filters as $fil => $vol) { // geo filter if ($fil == 'geo') { $min = (float) (isset($vol['min']) ? $vol['min'] : 0); $point = explode(' ', str_replace('POINT(', '', trim($vol['point'], ')'))); $this->client->setGeoAnchor('latitude', 'longitude', (float) $point[1] * ( pi() / 180 ), (float) $point[0] * ( pi() / 180 )); $this->client->setFilterFloatRange('@geodist', $min, (float) $vol['buffer']); // usual filter } else if ($fil === 'range'){ foreach ($vol as $attr=>$range) $this->client->SetFilterRange($attr, $range['min'], $range['max']); } else { $this->client->SetFilter($fil, (is_array($vol)) ? $vol : array($vol)); } } } return $this; }
It allows to make SetFilterRange() API call.
Usage:
$searchCriteria->filters = array('range' => array( 'date'=>array('min'=>$time_from, 'max'=>$time_to), 'age'=>array('min'=>$min_age, 'max'=>$max_age), ));
orderby bug
Hi,
this is my orderby function:
/** * @brief set matches sorting, SQL-like syntax - 'order_by expression' * @param array $orders * @return $this chain */ public function orderby($orders = null) { $this->criteria->orders = $orders; if ($orders) { array_walk($orders, function(&$item, $key) { $item = $key . ' ' . $item; }); $this->client->SetSortMode(SPH_SORT_EXTENDED, implode(',', $orders)); } return $this; }
filters functions (with floating support), thx berza:
/** * @brief set query filters, SQL-like syntax - 'additional where_condition' * @param array $filters * @return $this chain */ public function filters($filters) { $this->criteria->filters = $filters; //set filters if ($filters && is_array($filters)) { foreach ($filters as $fil => $vol) { // geo filter if ($fil == 'geo') { $min = (float) (isset($vol['min']) ? $vol['min'] : 0); $point = explode(' ', str_replace('POINT(', '', trim($vol['point'], ')'))); $this->client->setGeoAnchor('latitude', 'longitude', (float) $point[1] * ( pi() / 180 ), (float) $point[0] * ( pi() / 180 )); $this->client->setFilterFloatRange('@geodist', $min, (float) $vol['buffer']); // usual filter } else if ($fil === 'range'){ foreach ($vol as $attr=>$range) { if (is_float($range['min']) && is_float($range['max'])) { $this->client->SetFilterFloatRange($attr, $range['min'], $range['max']); } else { $this->client->SetFilterRange($attr, $range['min'], $range['max']); } } } else { $exclude = false; if(is_array($vol) && isset($vol['exclude'])) { $exclude = (bool) $vol['exclude']; unset($vol['exclude']); } $this->client->SetFilter($fil, (is_array($vol)) ? $vol : array($vol), $exclude); } } } return $this; }
How to use paginator?
how to use paginator in view?
Re: How to use paginator?
I get all result id, because if you use paginator in search component, you doesn't know result count, and page number.
can you post some code sample?
shark
I also don't know how to do on pagiation.
can you post some code sample?
limit the results
you do not need to get all id's to count total items found. The results array that returned by sphinxAPI along with [matches] returned a [total], [total_found], [request_time], etc rows. You need the total_found row. You can limit matches to 1 but you will see total found as well.
Error in DGSphinxSearch
Search by criteria Object:
...
$searchCriteria->orders = array('f_name' => 'ASC');
Error:
Argument 1 passed to DGSphinxSearch::orderby() must be an instance of DGSort, array given
How to fix:
$searchCriteria->orders = 'f_name ASC, product_id DESC';
public function orderby($orders = null) { $this->criteria->orders = $orders; if ($orders) { $this->client->SetSortMode(SPH_SORT_EXTENDED, $orders); } return $this; }
How to sort by geo?
I use
if ($fil == 'geo') { $min = (float) (isset($vol['min']) ? $vol['min'] : 0); $point = explode(' ', str_replace('POINT(', '', trim($vol['point'], ')'))); $this->client->setGeoAnchor('latitude', 'longitude', (float) $point[1] * ( pi() / 180 ), (float) $point[0] * ( pi() / 180 )); $this->client->setFilterFloatRange('@geodist', $min, (float) $vol['buffer']);
But I don't know how to sort by geo.
How to cache result?
How to cache result?
I use Search by criteria Object.
solution of don't working pagination
You must call twice: Yii::app()->search. I solved problem this way:
$searchCriteria = new stdClass(); $searchCriteria->select = '*'; $searchCriteria->query = '@tags *'.$term.'*'; $searchCriteria->from = 'test1'; $pages = new CPagination(); $pages->pageSize =24; $resArray = Yii::app()->search->setMatchMode(SPH_MATCH_ANY)->searchRaw($searchCriteria); $pages->itemCount = $resArray['total']; $searchCriteria->paginator = $pages; $resArray = Yii::app()->search->setMatchMode(SPH_MATCH_ANY)->searchRaw($searchCriteria);
How to show sphinx result data to datagrid as $dataprovider
Hi all....
How to show sphinx result data to datagrid as $dataprovider?
please send here example guidance.**
Thank a lot.
failed to implement as $dataprovider TbGridView .
Hi.. this is my code on view.
i implement to TbGridView.
$resArray = Yii::app()->search->setMatchMode(SPH_MATCH_ANY)->searchRaw($searchCriteria);
$this->widget('bootstrap.widgets.TbGridView', array( 'dataProvider' => $resArray, 'id' => 'order-grid', 'type' => 'striped', 'columns' => array( array( 'header' => Yii::t('order', 'Jumlah'), 'value' => '$data[\'catalogid\']', ), ), ));
i get error messages :
Fatal error: Call to a member function getData() on a non-object in C:\xampp\htdocs\myproject\vendor\yiisoft\yii\framework\zii\widgets\CBaseListView.php on line 111
how to fill sphinx data result into datagrid as $dataprovider ?
thank you.
solved
wow. i confused using this extension.
i execute sphinx not use this. but i use DAO regular.
this is guide to execute yii + sphinx and showing result data to grid.
thanks all..
thanks yii..
Data provider for sphinx search
Anyone who needs data provider as search result can use additional component written by Yuri! in this thread. It also supports pagination.
Hope that would be useful. Thanks for providing this extension, anyway!
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.