2008-12-28 14 views
6

Estoy haciendo una función de búsqueda para mi sitio web, que encuentra resultados relevantes de una base de datos. Estoy buscando una manera de contar las ocurrencias de una palabra, pero necesito asegurarme de que haya límites de palabras en ambos lados de la palabra (para que no termine con "triple" cuando quiero "desgarrar").Cuente las ocurrencias de una palabra en una fila en MySQL

¿Alguien tiene alguna idea?


La gente ha entendido mal mi pregunta:

¿Cómo puedo contar el número de tales ocurrencias dentro de una sola fila?

Respuesta

2

Este no es el tipo de cosas en las que las bases de datos relacionales son muy buenas, a menos que pueda usar indexación de texto completo, y usted ya ha declarado que no puede hacerlo, ya que está usando InnoDB. Te sugiero que selecciones tus filas relevantes y hagas el recuento de palabras en el código de tu aplicación.

0

Algo como esto debería funcionar:

select count (*) de la tabla donde nombredecampo REGEXP '[[: <:]] palabra [[:>:]]';

Los detalles sangrientos están en el manual de MySQL, sección 11.4.2.

+2

Esto comprueba el número de filas contienen la cadena de búsqueda. El interlocutor quiere contar con qué frecuencia la cadena de búsqueda está contenida en cada fila. – flu

0

Algo como LIKE o REGEXP no se escalará (a menos que sea una coincidencia de prefijo del extremo izquierdo).

Considere en su lugar usar un fulltext index para lo que quiere hacer.

select count(*) from yourtable where match(title, body) against ('some_word'); 
+0

No se puede hacer el índice de texto completo ... Estoy usando InnoDB. – stalepretzel

0

He utilizado la técnica como se describe en el siguiente enlace. El método usa las funciones length y replace de MySQL.

Keyword Relevance

1

Usted puede tratar de esta manera pervertida:

SELECT 
(LENGTH(field) - LENGTH(REPLACE(field, 'word', '')))/LENGTH('word') AS `count` 
ORDER BY `count` DESC 
  • Esta consulta puede ser muy lento
  • se ve bastante feo
  • replace() es entre mayúsculas y minúsculas
+0

Esto contará * cadenas *, no * palabras *. – RandomSeed

1

Puede solucionar el problema de la función REPLACE() sensible a mayúsculas y minúsculas de MySQL mediante el uso de LOWER().

Es descuidado, pero en mi extremo esta consulta funciona bastante rápido.

Para acelerar las cosas, recupero el conjunto de resultados en una selección que he declarado como una tabla derivada en mi consulta 'externa'. Como mysql ya tiene los resultados en este punto, el método de reemplazo funciona bastante rápido.

Creé una consulta similar a la siguiente para buscar varios términos en varias tablas y columnas múltiples.Puedo obtener una 'relevancia' número equivalente a la suma de la cuenta de todas las ocurrencias de todos los términos que se encuentran en todas las columnas buscó

SELECT DISTINCT ( 
((length(x.ent_title) - length(replace(LOWER(x.ent_title),LOWER('there'),'')))/length('there')) 
+ ((length(x.ent_content) - length(replace(LOWER(x.ent_content),LOWER('there'),'')))/length('there')) 
+ ((length(x.ent_title) - length(replace(LOWER(x.ent_title),LOWER('another'),'')))/length('another')) 
+ ((length(x.ent_content) - length(replace(LOWER(x.ent_content),LOWER('another'),'')))/length('another')) 
) as relevance, 
x.ent_type, 
x.ent_id, 
x.this_id as anchor, 
page.page_name 
FROM ( 
(SELECT 
'Foo' as ent_type, 
sp.sp_id as ent_id, 
sp.page_id as this_id, 
sp.title as ent_title, 
sp.content as ent_content, 
sp.page_id as page_id 
FROM sp 
WHERE (sp.title LIKE '%there%' OR sp.content LIKE '%there%' OR sp.title LIKE '%another%' OR sp.content LIKE '%another%') AND (sp_content.title NOT LIKE '%goes%' AND sp_content.content NOT LIKE '%goes%') 
) UNION (
    [search a different table here.....] 
) 
) as x 
JOIN page ON page.page_id = x.page_id 
WHERE page.rstatus = 'ACTIVE' 
ORDER BY relevance DESC, ent_title; 

Espero que esto ayude a alguien

- Seacrest cabo

+0

Esto contará * cadenas *, no * palabras *. – RandomSeed

-3

Se depende de qué DBMS está utilizando, algunos permiten la escritura de UDF que podrían hacer esto.

0

Si desea buscar algo como Sphinx o Lucene, considero que Sphinx (como un indexador independiente de texto completo) es mucho más fácil de configurar y ejecutar. Funciona rápido y genera los índices muy rápido. Incluso si estuviera usando MyISAM, sugeriría usarlo, tiene mucha más potencia que un índice de texto completo de MyISAM.

También se puede integrar (algo) con MySQL.

1

crear una función definida por el usuario como este y lo utilizan en su consulta

DELIMITER $$ 

CREATE FUNCTION `getCount`(myStr VARCHAR(1000), myword VARCHAR(100)) 
    RETURNS INT 
    BEGIN 
    DECLARE cnt INT DEFAULT 0; 
    DECLARE result INT DEFAULT 1; 

    WHILE (result > 0) DO 
    SET result = INSTR(myStr, myword); 
    IF(result > 0) THEN 
     SET cnt = cnt + 1; 
     SET myStr = SUBSTRING(myStr, result + LENGTH(myword)); 
    END IF; 
    END WHILE; 
    RETURN cnt;  

    END$$ 

DELIMITER ; 

creo que sirve Refer This

Cuestiones relacionadas