2011-04-27 77 views
0

首先: - 我不能使用狮身人面像,因为我使用共享主机 - 我不喜欢谷歌解决方案即。自定义搜索有这些愚蠢的广告和网站搜索不是免费的php/mysql:自定义网站搜索

我想创建自己的搜索mechanizm。我有页表,我想通过关键字搜索页面内容,并且在结果页上我想显示与所需关键字匹配的文本的一部分(与谷歌相同)。

先进

+0

参考:[mySQL手册:全文搜索功能](http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html) – 2011-04-27 23:02:21

+1

可能重复[如何制作搜索引擎的网站?](http:// stackoverflow。问题/ 2810015 /如何使一个搜索引擎的网站) – 2011-04-27 23:03:01

+0

我忘了noitce,我有alrady设置我的数据库为innoDB,所以我不能使用全文搜索。 – Milos 2011-04-28 09:04:02

回答

1

然后THX你有两个(半)选择:你想要搜索

  • 写你自己的索引,事中的数据

    • 使用MyISAM引擎
    • 更改托管或更改DBMS(1/2解决方案)

    下面是如何做的简短版本第二选项

    假设您要搜索文章的内容。 基本上你必须创建一个你可能想要搜索的所有单词的索引。

    下面的代码取自书SQL Antipatterns和修改只有微小的一点。

    我会认为你想索引的文章:

    CREATE TABLE Articles(
        article_id INT AUTO_INCREMENT, 
        title VARCHAR(120), 
        content TEXT, 
        PRIMARY KEY (article_id) 
    ); 
    

    你需要的关键词表(每个关键字可以在多篇文章):

    CREATE TABLE Keywords(
        keyword_id INT AUTO_INCREMENT, 
        keyword VARCHAR(40) UNIQUE NOT NULL, 
        PRIMARY KEY (keyword_id) 
    ); 
    

    现在的表来实现多一对多的关系:

    CREATE TABLE ArticlesKeywords(
        keyword_id INT, 
        article_id INT, 
        PRIMARY KEY (keyword_id , article_id), 
        FOREIGN KEY (keyword_id) REFERENCES Keywords(keyword_id), 
        FOREIGN KEY (article_id) REFERENCES Articles(article_id) 
    ); 
    

    然后你创建一个存储过程,它填充您的索引机制:

    CREATE PROCEDURE ArticlesSearch(keyword VARCHAR(40)) 
    BEGIN 
        SET @keyword = keyword; 
        PREPARE s1 FROM 'SELECT MAX(keyword_id) INTO @k FROM Keywords 
         WHERE keyword = ?'; 
        EXECUTE s1 USING @keyword; 
        DEALLOCATE PREPARE s1; 
        IF (@k IS NULL) THEN 
    
         PREPARE s2 FROM 'INSERT INTO Keywords (keyword) VALUES (?)'; 
         EXECUTE s2 USING @keyword; 
         DEALLOCATE PREPARE s2; 
    
         SELECT LAST_INSERT_ID() INTO @k; 
    
         PREPARE s3 FROM 'INSERT INTO ArticlesKeywords (article_id, keyword_id) 
         SELECT article_id, ? FROM Articles 
         WHERE title REGEXP CONCAT(''[[:<:]]'', ?, ''[[:>:]]'') 
          OR content REGEXP CONCAT(''[[:<:]]'', ?, ''[[:>]]'')'; 
         EXECUTE s3 USING @k, @keyword, @keyword; 
         DEALLOCATE PREPARE s3; 
    
        END IF; 
    
        PREPARE s4 FROM 'SELECT b.*FROM Articles b 
         JOIN ArticlesKeywords k USING (article_id) 
         WHERE k.keyword_id = ?'; 
        EXECUTE s4 USING @k; 
        DEALLOCATE PREPARE s4; 
    END 
    

    现在您可以使用此过程搜索关键字索引。

    CALL ArticlesSearch('OMG');

    的解决方案的最后一部分是确保每一个新的文章被自动索引:

    CREATE TRIGGER Articles_Insert AFTER INSERT ON Articles 
    FOR EACH ROW 
    BEGIN 
        INSERT INTO ArticlesKeywords (article_id, keyword_id) 
         SELECT NEW.article_id, k.keyword_id FROM Keywords k 
         WHERE NEW.content REGEXP CONCAT('[[:<:]]', k.keyword, '[[:>:]]') 
         OR NEW.title REGEXP CONCAT('[[:<:]]', k.keyword, '[[:>:]]'); 
    END 
    

    P.S.我从来没有需要测试这种方法,这就是为什么我不能保证它会工作。

  • +0

    纠正我,如果我错了,你必须事先定义关键字。嗯,这是否意味着没有结果,如果我没有连接文章与键入关键字。我是回应维护关键字列表数据,是我? – Milos 2011-04-28 09:01:33

    +0

    是的,情况就是这样。如果你想索引每篇文章中的每个单词,你必须添加额外的脚本,它将所有*有用的*单词,并将它们广告索引,然后将文章本身保存在数据库中。 – 2011-04-28 10:58:13

    +0

    嗯,这是不错的选择。谁需要索引文本中的每个单词。根据结果​​页面还有一个问题。 REsult页面应该以表单页面标题+匹配的内容。如何显示与关键字匹配的文章的一部分。 – Milos 2011-04-28 12:28:09