【问题标题】:php/mysql: Custom site searchphp/mysql:自定义站点搜索
【发布时间】:2011-08-14 06:38:24
【问题描述】:

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

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

感谢高级

【问题讨论】:

标签: php mysql search


【解决方案1】:

那么你有两个(半个)选择:

  • 使用 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

.

附注我从来不需要测试这种方法,这就是为什么我不能保证它会起作用。

【讨论】:

  • 如果我错了,请纠正我,您必须提前定义关键字。嗯,如果我没有将文章与键入的关键字联系起来,这是否意味着没有结果。我是响应维护关键字列表的数据,是吗?
  • 是的,就是这样。如果您想索引每篇文章中的每个单词,则必须添加额外的脚本,该脚本会获取所有 有用 单词并将它们添加到索引中,然后再将文章本身保存到数据库中。
  • 嗯,这是个不错的选择。谁需要索引文本中的每个单词。根据结果​​页面还有一个问题。结果页面应该是表单页面标题+匹配的内容。如何显示与关键字匹配的部分文章。
  • 您必须在 PHP 端完成该部分 - strpos()。 SQL 只会返回包含关键字的文章。
猜你喜欢
  • 2015-03-29
  • 2013-11-16
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多