代码之家  ›  专栏  ›  技术社区  ›  stalepretzel

计算MySQL中一行中一个词的出现次数

  •  6
  • stalepretzel  · 技术社区  · 16 年前

    我正在为我的网站创建一个搜索功能,它可以从数据库中找到相关的结果。我正在寻找一种计算单词出现次数的方法,但我需要确保单词的两边都有单词边界(所以当我想要“rip”时,我不会以“triple”结尾)。

    有人有什么想法吗?


    人们误解了我的问题:

    我怎么计算这种情况的发生次数呢 在一行之内?

    9 回复  |  直到 11 年前
        1
  •  2
  •   Alison R.    15 年前

    这不是关系数据库擅长的事情,除非您可以使用全文索引,而且您已经声明了不能,因为您使用的是InnoDB。我建议您选择相关的行,并在应用程序代码中进行单词计数。

        2
  •  1
  •   Slava Popov    15 年前

    你可以尝试这种扭曲的方式:

    SELECT 
    (LENGTH(field) - LENGTH(REPLACE(field, 'word', ''))) / LENGTH('word') AS `count`
    ORDER BY `count` DESC
    
    • 这个查询可能非常慢
    • 看起来很难看
    • replace()区分大小写
        3
  •  1
  •   Mutix question    13 年前

    你可以克服MySQL区分大小写的问题 REPLACE() 使用的函数 LOWER() .

    它很草率,但在我的末尾,这个查询运行得相当快。

    为了加快速度,我在select中检索结果集,我在“outer”查询中将其声明为派生表。由于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;
    

    希望这能帮助别人

    --摆脱困境

        4
  •  1
  •   Community CDub    7 年前

    创建这样的用户定义函数并在查询中使用它

    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 ;
    

    希望它有帮助 Refer This

        5
  •  0
  •   Alex    16 年前

    这样的方法应该有效:

    从表中选择count(*),其中fieldname regexp'[[:<:]]word[[:>:]';

    详细信息见MySQL手册第11.4.2节。

        6
  •  0
  •   ʞɔıu    16 年前

    类似于或regexp的东西不会缩放(除非它是最左边的前缀匹配)。

    考虑改用 fulltext index 为了你想做的。

    select count(*) from yourtable where match(title, body) against ('some_word');
    
        7
  •  0
  •   Rishi Agarwal    16 年前

    我使用了下面链接中描述的技术。方法使用 length replace MySQL的功能。

    Keyword Relevance

        8
  •  0
  •   Paul    14 年前

    如果你想要一个搜索,我建议像斯芬克斯或露西,我发现斯芬克斯(作为一个独立的全文索引器)是更容易设置和运行。它运行得很快,生成索引的速度也很快。即使您使用的是myisam,我建议您使用它,它比myisam的全文索引具有更大的功能。

    它还可以(在一定程度上)与MySQL集成。

        9
  •  -3
  •   wlk    14 年前

    这取决于您使用的是什么DBMS,有些允许编写可以做到这一点的UDF。