Подсчет вхождений слова подряд в MySQL - PullRequest
6 голосов
/ 28 декабря 2008

Я делаю функцию поиска для моего сайта, которая находит релевантные результаты из базы данных. Я ищу способ подсчета вхождений слова, но мне нужно убедиться, что по обеим сторонам слова есть границы слов (поэтому я не получаю «тройной», когда хочу «разорвать»).

У кого-нибудь есть идеи?


Люди неправильно поняли мой вопрос:

Как подсчитать количество таких случаев в одной строке?

Ответы [ 9 ]

2 голосов
/ 16 февраля 2010

Это не та вещь, в которой реляционные базы данных очень хороши, если только вы не можете использовать полнотекстовое индексирование, и вы уже заявили, что не можете, поскольку вы используете InnoDB. Я бы предложил выбрать соответствующие строки и подсчитать количество слов в коде приложения.

1 голос
/ 26 июля 2013

создайте пользовательскую функцию, подобную этой, и используйте ее в своем запросе

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 ;

Надеюсь, это поможет См. Это

1 голос
/ 18 августа 2010

Вы можете решить проблему чувствительной к регистру функции REPLACE() в mysql, используя LOWER().

Это небрежно, но с моей стороны этот запрос выполняется довольно быстро.

Чтобы ускорить процесс, я извлекаю набор результатов из выбора, который я объявил как производную таблицу в моем «внешнем» запросе. Поскольку mysql уже имеет результаты на данный момент, метод replace работает довольно быстро.

Я создал запрос, аналогичный приведенному ниже, для поиска нескольких терминов в нескольких таблицах и нескольких столбцах. Я получаю число «релевантность», эквивалентное сумме подсчета всех вхождений всех найденных поисковых терминов во всех столбцах, в которых был произведен поиск

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;

Надеюсь, это кому-нибудь поможет

- Seacrest out

1 голос
/ 16 февраля 2010

Вы можете попробовать этот извращенный способ:

SELECT 
(LENGTH(field) - LENGTH(REPLACE(field, 'word', ''))) / LENGTH('word') AS `count`
ORDER BY `count` DESC
  • Этот запрос может быть очень медленным
  • выглядит довольно некрасиво
  • REPLACE () чувствителен к регистру
0 голосов
/ 05 декабря 2010

Если вы хотите выполнить поиск, я бы посоветовал что-то вроде Sphinx или Lucene, я считаю, что Sphinx (как независимый полнотекстовый индексатор) намного проще в настройке и запуске. Он работает быстро и очень быстро генерирует индексы. Даже если бы вы использовали MyISAM, я бы посоветовал использовать его, он обладает гораздо большими возможностями, чем полнотекстовый индекс MyISAM.

Он также может (частично) интегрироваться с MySQL.

0 голосов
/ 18 августа 2010

Это зависит от того, какую СУБД вы используете, некоторые позволяют писать UDF, которые могут это сделать.

0 голосов
/ 29 декабря 2008

Я использовал технику, описанную в ссылке ниже. Метод использует функции length и replace MySQL.

Релевантность ключевого слова

0 голосов
/ 28 декабря 2008

Что-то вроде LIKE или REGEXP не будет масштабироваться (если только это не крайний левый префикс).

Попробуйте вместо этого использовать полнотекстовый индекс для того, что вы хотите сделать.

select count(*) from yourtable where match(title, body) against ('some_word');
0 голосов
/ 28 декабря 2008

Примерно так должно работать:

выберите количество (*) из таблицы, где имя поля REGEXP '[[: <:]] слово [[:>:]]';

Подробные сведения приведены в руководстве по MySQL, раздел 11.4.2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...