Leccion aprendida instalar sphinx en ubuntu

Hola, escribo esto no solo paraque otros no caigan en el mismo error, si no que tambien para que yo no vuelva a cometerlo.

Instalar sphinx search en ubuntu puede ser tan facil como escribir;
sudo apt-get install sphinxsearch

Pero si queremos usar sphinx con el stemmer haciendo mas potentes nuestras busquedas el camino es cuesta arriba…

1) descarga y extrae la version estable de sphinx;
wget http://sphinxsearch.com/files/sphinx-0.9.9.tar.gz
tar xzf sphinx-0.9.9.tar.gz

2) instalemos las porqueris para usar mysql
sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install build-essential
sudo apt-get install libmysqlclient15-dev

3) instalemos el stemmer
cd sphinx-0.9.9/
wget http://snowball.tartarus.org/dist/libstemmer_c.tgz
tar xzf libstemmer_c.tgz

4) instalemos todo, como veran yo lo instale en /usr/local/sphinx ustedes pueden instalarlo donde se les cante
./configure --prefix=/var/sphinx --with-libstemmer --with-mysql-includes=/usr/include/mysql --with-mysql-libs=/usr/lib/mysql
make
sudo make install

Luego tienen que crear el archivo de configuracion de sphinx y todo lo demas que ya deberian saber hacer.

Creando los indice.
/path/instalacion/indexer –all -c /path/de/configuracion/sphinx.conf

Luego tenes que cargar el demonio
/path/instalacion/searchd /path/de/configuracion/sphinx.conf

OJO! yo como un boludo en vez de searchd puse search, que es el binario para realizar busquedas, constantemente me tiraba error y pense que me habia mandado una cagada con el archivo de configuracion.

Bueno ahi lo tienen, facil no?

Anuncios

sql: joins vs multiple selects

Pese a que el saber popular dice que hacer un select multiple*(1) versus un select con joins*(2) es mas lento.

*(1) SELECT link_id,sum(vote_value) FROM links,votes WHERE link_id=vote_link_id AND vote_type=’links’ AND vote_value>0 AND link_date > DATE_SUB(NOW(), INTERVAL 1 year) GROUP BY link_id
*(2) SELECT link_id,sum(vote_value) FROM links INNER JOIN votes ON (link_id=vote_link_id AND vote_type=’links’ AND vote_value>0) WHERE link_date > DATE_SUB(NOW(), INTERVAL 1 year) GROUP BY link_id

Para sacarme la duda cree una script que crea usuarios, enlaces, comentarios y votos (positivos y negativos) en meneame.

Luego tome las diferentes queries que usaban multiples tablas para el calculo del karma (el archivo /scripts/karma9.php) y las compare con las joins, en todas las consultas agregue el prefijo SQL_NO_CACHE

El resultado final contra todo lo que esperaba fue no concluyente…
Seletcs multiples total took: 587
Selects joins total took: 600

Como no me gusta rendirme facilmente elimine todos los indices y corri de nuevo los test. Obteniendo el siguiente resultado;
Seletcs multiples total took: 118023
Selects joins total took: 117221

A tener en cuenta, las consultas siempre fueron hechas entre dos tablas, si fueran de mas tablas segun la documentacion de sql: nested joins

Conclusion
Como conclusion podemos afirmar que los indices vamos a lograr consultas muy rapidas, pero esto se paga, los inserts, deletes y updates de una campo indice van a ser mas lentos, debido a que los indices deben ser regenerados. Tambien se paga con espacio ya que los indices ocupan memoria.

cakephp y los campos de tipo enum

Actualmente como sabran cakephp no soporta los campos del tipo enum, por que al importar los fixtures en los tests podemos encontrarnos con algunos problemas.

Cree un simple patch para que transforme el enum a un campo de texto, voy abrir un ticket a ver si lo pueden agregar al datasources dbo.

Mientras tanto si alguno de tus modelos usa campos enum puedes agregar lo siguiente en el fixture;

class ModelnameFixture extends CakeTestFixture {
	function create(&$db) {
		// enum support in test fixture, by Eugenio Fage
		foreach ($this->fields as $field) {
			if(substr($field['type'],0,4)=='enum') $db->columns[$field['type']] = $db->columns['string'];
		}

		return parent::create($db);
	}
}

Saludos!

megusta / fblike script

EL REPOSITORIO HA SIDO CAMBIADO, PUEDES DESCARGAR LA NUEVA VERSION DESDE AQUI http://www.mediafire.com/?ctjst16e221y53x

Desarrolle una pequeña script para script para crear frases en facebook, pueden descargarla desde;
http://code.google.com/p/fblike/

Pueden ver una pequeña demostracion aqui

Que es?

Fblike es una simple script para que los usuarios de facebook puedan crear frases y compartirlas con sus amigos. Puedes ver una demo del sistema en;

Inspiracion

fblike fue inspirado en base a estos sitios;

Como instalar fblike

  1. crea la base de datos y la tabla, las sentencias sql para crear las tablas se encuentran en base.sql
  2. configura los datos para conectarte a la base de datos en app/config/database.php
  3. crea una aplicacion en facebook http://developers.facebook.com/setup/
    • ingresa a la configuracion de la aplicacion que recien creaste
    • ve a la pestaña que dice Facebook integration
    • elige una direccion dentro de facebook (opcion Página de trabajo)
    • en canvas URL escribe direccion_donde_esta_fblike/fbapp
    • en canvas type seleccion iframe
  4. configura los datos para usar la facebook app en app/config/fb-config.php
  5. una vez que la probaste y funciona no olvides ponerlo en modo de produccion, para ello vea a app/config/core.php busca Configure::write(‘debug’, 3); y cambialo por Configure::write(‘debug’, 0);

DESCARGAR

http://code.google.com/p/fblike/downloads/detail?name=fblike.zip

cacheando queries de forma facil

Idea original tomada de: http://www.endyourif.com/caching-queries-in-cakephp/

Una optimizacion comun es cachear queries… navegando por ahi me encontre con un articulo donde simplemente reescriben el metodo find de los modelos para cachear las queries, lo modifique un poquito y asi quedo;

app_model.php

class AppModel extends Model {
	/**
	 * 
	 * Cache find queries
	 */ 
    function find($conditions = null, $fields = array(), $order = null, $recursive = null) {
    	if (!empty($fields['cacheKey'])) {
    		$cacheConfig = 'query';
			if (!empty($fields['cacheConfig'])){
      			$cacheConfig = $fields['cacheConfig'];
    		}
    		
    		$cacheName = $this->name . '-' . $fields['cacheKey'];
			
    		if (($data = Cache::read($cacheName, $cacheConfig)) === false) {
				$data = parent::find($conditions, $fields, $order, $recursive);
				Cache::write($cacheName, $data, $cacheConfig);
			}
    	}else{
    		$data = parent::find($conditions, $fields, $order, $recursive);
    	}
    	
    	return $data;
    }
}

Como veran por defecto usa la configuracion de cache llamada ‘query’, asi que vamos a tener que agregar esto en;

config/core.php

Cache::config('query', array(
 'engine' => 'File',
 'duration'=> '+20 minutes',
 'probability'=> 100,
 'path' => CACHE . 'queries' . DS,
 ));

Ademas tendremos que crear en el directorio de cache el directorio queries, alli se salvaran todas las queries, si en vez de usar el file engine podemos cambiarlo por memcache tocando la configuracion (lo que recien escribimos en core.php).

USO

Cuando queremos cachear un find solo agregamos lo siguiente al array options;

$this->Modelo->find('all',array('cacheKey'=>'llave','conditions'=>2));
$this->Modelo->find('all',array('cacheKey'=>'llave','cacheConfig'=>'memcached','conditions'=>2));

PAZ!