• " level="2">搜索 version
    • 环境配置
    • 搜索页面入口?
    • 如何主动更新索引?
    • 如何根据输入的关键字获取索引结果?

    " class="reference-link">搜索 version

    环境配置

    MySQL 5.6前,只有 MyISAM 引擎支持全文搜索,MySQL 5.6 InnoDB 也支持全文索引。

    配置mysql.cnf

    1. #mysql指定了最小字符长度,默认是4,必须要匹配大于4的才会有返回结果
    2. ft_min_word_len = 2

    字段是否加入全文搜索

    图片

    搜索页面入口?

    1. http://you_domain.com/index.php?g=Search

    如何主动更新索引?

    更新索引,更新需要检索字段的分词

    1. $SearModel::search_api($id, $data, $modelid);
    2. # data 为传入该行数据 ,由$modelid + $id 两条件筛选出来

    如何根据输入的关键字获取索引结果?

    思路:先把关键字分词,然后进行检索。

    核心代码

    1. //分词结果
    2. if ($this->config['dzsegment']) {
    3. //用discuz的分词接口,http调用,比较耗时
    4. $segment_q = D('Search/Search')->discuzSegment($q);
    5. } else {
    6. //内置的分词方法
    7. $segment_q = D('Search/Search')->segment($q);
    8. }
    9. if (!empty($segment_q[0]) && $this->config['segment']) {
    10. $words = $segment_q;
    11. $segment_q = implode(' ', $segment_q);
    12. $where['_string'] = " MATCH (`data`) AGAINST ('{$segment_q}' IN BOOLEAN MODE) ";
    13. } else {
    14. //不推荐,性能差。若分词失败什么的,用最暴力的模糊查询
    15. $likeList = explode(' ', $q);
    16. if (count($likeList) > 1) {
    17. foreach ($likeList as $k => $rs) {
    18. $likeList[$k] = "%{$rs}%";
    19. }
    20. $where['data'] = array('like', $likeList, 'or');
    21. } else {
    22. $where['data'] = array('like', "%{$q}%");
    23. }
    24. $words = array($q);
    25. }
    26. //查询结果缓存
    27. if ($cachetime) {
    28. //统计
    29. $count = M('Search')->where($where)->cache(true, $cachetime)->count();
    30. $page = page($count, $pagesize);
    31. $result = M('Search')->where($where)->cache(true, $cachetime)->limit($page->firstRow . ',' . $page->listRows)->order($order)->select();
    32. } else {
    33. $count = M('Search')->where($where)->count();
    34. $page = page($count, $pagesize);
    35. $result = M('Search')->where($where)->limit($page->firstRow . ',' . $page->listRows)->order($order)->select();
    36. }