This forum is in READ-ONLY mode.
You can look around, but if you want to ask a new question, please use the new forum.
Home » plugins » Search plugins » A proposal to sfSphinxPlugin: sfSphinxPager.class.php
A proposal to sfSphinxPlugin: sfSphinxPager.class.php [message #67854] Tue, 16 December 2008 10:29 Go to next message
hungdao  is currently offline hungdao
Messages: 2
Registered: December 2008
Junior Member
Hi there, I have been using sphinx search and sfSphinxPlugin. However, there is only one annoying thing with Sphinx is that I cant use the pagination with models in Sphinx. So here is my proposal for a so-called sfSphinxPager

For example, I want to have search engine to display books which have a specific keyword in either title, description or tag:

Config
source book
{
	type					= mysql

	sql_host				= localhost
	sql_user				= root
	sql_pass				= *******
	sql_db					= whatever
	sql_port				= 3306	# optional, default is 3306

	sql_query				= \
		SELECT id, author_id, title, description, created_at, rate, view, tag \
		FROM book
	sql_attr_uint = author_id

	sql_query_info			= SELECT * FROM book WHERE id=$id
}


index book
{
	source					= book
	path					= D:\Sphinx\data\book
	docinfo					= extern
	charset_type			= sbcs
}


The old usage with sfPropelPager
$pager = new sfPropelPager('Book', $booksPerPage);
$pager->setCriteria($c);
$pager->setPage($page);
$pager->setPeerMethod('doSelectJoinAll');
$pager->init();


And the new one
$pager = new sfSphinxPager('Book', $booksPerPage);
$pager->setKeyword($keyword);
$pager->setFilter(BookPeer::AUTHOR_ID, $userId);
//$pager->setCriteria($c); no criteria, use sphinx filters instead
$pager->setPage($page);
$pager->setPeerMethod('retrieveByPKsJoinAll');
$pager->init();


The problem with sfSphinxPager is that you cant use criteria and you have to use sfSphinxPager::setFilter() instead. It is a proxy to sfSphinxClient::setFilter() so I think you should read the sphinx php api a little bit.

Tell me what do you think about the idea and how can I improve it...

[Updated] I have modified the retrieveObject method. Now it works just like sfPropelPager except for the criteria.

[Updated on: Thu, 18 December 2008 16:44]


Symfony + Online comics = MahShelf
Re: A proposal to sfSphinxPlugin: sfSphinxPager.class.php [message #71362 is a reply to message #67854 ] Tue, 03 February 2009 22:54 Go to previous messageGo to next message
sh1ny  is currently offline sh1ny
Messages: 16
Registered: June 2008
Junior Member
Can you repost this please ? I cannot download the attachment Sad
Re: A proposal to sfSphinxPlugin: sfSphinxPager.class.php [message #71384 is a reply to message #71362 ] Wed, 04 February 2009 10:37 Go to previous messageGo to next message
hungdao  is currently offline hungdao
Messages: 2
Registered: December 2008
Junior Member
I repost the source code in this post, hope the others wont mind
<?php

class sfSphinxPager extends sfPager
{
  protected
    $peer_method_name       = 'retrieveByPKsJoinAll', // FIXME: change to retrieveByPKs
    $peer_count_method_name = 'doCount',
    $keyword = null,
    $sphinx = null;
    //$res = null;
    

  public function __construct($class, $maxPerPage = 10)
  {
    parent::__construct($class, $maxPerPage);

    $this->tableName = constant($this->getClassPeer().'::TABLE_NAME');
    $options = array(
	    'limit'   => $maxPerPage,
	    'offset'  => 0,
	  	'mode'    => sfSphinxClient::SPH_MATCH_EXTENDED,
	    'weights' => array('title'=>100, 'description'=>1, 'tag'=>10), // FIXME: change the weight
	    'sort'    => sfSphinxClient::SPH_SORT_EXTENDED,
	    'sortby'  => '@weight DESC',
	  );
	  $this->sphinx = new sfSphinxClient($options);
  }

  public function init()
  {	 
		$hasMaxRecordLimit = ($this->getMaxRecordLimit() !== false);
    $maxRecordLimit = $this->getMaxRecordLimit();

    $res = $this->sphinx->Query($this->keyword, $this->tableName);
    $count = $res["total_found"];

    $this->setNbResults($hasMaxRecordLimit ? min($count, $maxRecordLimit) : $count);

    if (($this->getPage() == 0 || $this->getMaxPerPage() == 0))
    {
      $this->setLastPage(0);
    }
    else
    {
      $this->setLastPage(ceil($this->getNbResults() / $this->getMaxPerPage()));

      $offset = ($this->getPage() - 1) * $this->getMaxPerPage();

      if ($hasMaxRecordLimit)
      {
        $maxRecordLimit = $maxRecordLimit - $offset;
        if ($maxRecordLimit > $this->getMaxPerPage())
        {
          $limit = $this->getMaxPerPage();
        }
        else
        {
          $limit = $maxRecordLimit;
        }
      }
      else
      {
        $limit= $this->getMaxPerPage();
      }
      $this->sphinx->SetLimits($offset, $limit);
    }
  }

	protected function retrieveObject($offset)
  {
		$this->sphinx->SetLimits($offset - 1, 1);
		
  	$res = $this->sphinx->Query($this->keyword, $this->tableName);
  	if ($res['total_found'])
  	{
  		$ids = array();
		  foreach ($res['matches'] as $match)
		  {
		    $ids[] = $match['id'];
		  }
	
	    $results = call_user_func(array($this->getClassPeer(), $this->getPeerMethod()), $ids);
	    return is_array($results) && isset($results[0]) ? $results[0] : null;
  	}
  	else
  	{
  		return null;
  	}
  }

  public function getResults()
  {
  	$res = $this->sphinx->Query($this->keyword, $this->tableName);
  	if ($res['total_found'])
  	{
  		$ids = array();
		  foreach ($res['matches'] as $match)
		  {
		    $ids[] = $match['id'];
		  }
	
	    return call_user_func(array($this->getClassPeer(), $this->getPeerMethod()), $ids);
  	}
  	else
  	{
  		return array();
  	}
    
  }

  public function getPeerMethod()
  {
    return $this->peer_method_name;
  }

  public function setPeerMethod($peer_method_name)
  {
    $this->peer_method_name = $peer_method_name;
  }

  public function getPeerCountMethod()
  {
    return $this->peer_count_method_name;
  }

  public function setPeerCountMethod($peer_count_method_name)
  {
    $this->peer_count_method_name = $peer_count_method_name;
  }

  public function getClassPeer()
  {
    return constant($this->class.'::PEER');
  }
  
	public function setKeyword($k)
  {
    $this->keyword = $k;
  }
  
  /**
   * A proxy for Sphinx::SetSortMode()
   * set sort mode
   * @param integer $mode
   * @param string  $sortby
   */
  public function setSortMode($mode, $sortby = '')
  {
  	$this->sphinx->SetSortMode($mode, $sortby);
  }
  
  /**
   * A proxy for Sphinx::SetFilter()
   * set values set filter
   * only match records where $attribute value is in given set
   * @param string  $attribute
   * @param array   $values
   * @param boolean $exclude
   */
  public function setFilter($attribute, $values, $exclude = false)
  {
    $this->sphinx->SetFilter($attribute, $values, $exclude);
  }
  
  /**
   * set range filter
   * only match those records where $attribute column value is beetwen $min and $max
   * (including $min and $max)
   * @param string  $attribute
   * @param integer $min
   * @param integer $max
   * @param boolean $exclude
   */
  public function setFilterRange($attribute, $min, $max, $exclude = false)
  {
  	$this->sphinx->SetFilterRange($attribute, $min, $max, $exclude);
  }
  
}


Symfony + Online comics = MahShelf
Re: A proposal to sfSphinxPlugin: sfSphinxPager.class.php [message #71554 is a reply to message #67854 ] Thu, 05 February 2009 16:21 Go to previous messageGo to next message
sh1ny  is currently offline sh1ny
Messages: 16
Registered: June 2008
Junior Member
thanks Wink
sfSphinxPlugin config file [message #79941 is a reply to message #71554 ] Tue, 16 June 2009 14:31 Go to previous message
iamdecal  is currently offline iamdecal
Messages: 23
Registered: January 2008
Junior Member
looking at,

http://www.symfony-project.org/plugins/sfSphinxPlugin

i cant work out where the config file is supposed to be, and cant find the call for it in teh code to work out from there,

any clues?

D
Previous Topic:Plugin similar to script catalogue
Next Topic:TinyMCE plugin not getting installed
Goto Forum:
  

powered by FUDforum - copyright ©2001-2004 FUD Forum Bulletin Board Software