zoukankan      html  css  js  c++  java
  • 利用redis完成自动补全搜索功能(三)

      前面已经完成了分词和自动提示功能,最后把搜索结合在一起,来个完成的案例。当然最好还是用搜索分词解决,这个只是一个临时解决方案。

    其实加上搜索很简单,要做的就是3件事 

      1. 分词的时候,把有用词的id存进hash.

      2. 每次搜索的关键词,如果存在的自增

      3. 通过关键词把hash里的 id取出,然后通过id查询数据库即可。

    dist.php 分词

    <?php
    require './redis.php';
    
    //从数据库取出需要分词的数据
    $words = [
        ['name'=>'花讯','id'=>1],
        ['name'=>'nba','id'=>2],
        ['name'=>'nba直播','id'=>3],
        ['name'=>'nba赛事','id'=>4],
        ['name'=>'nba季后赛','id'=>5],
        ['name'=>'nba录像','id'=>6],
        ['name'=>'花讯品牌','id'=>7],
        ['name'=>'花讯女装','id'=>8],
        ['name'=>'花','id'=>9],
        ['name'=>'n','id'=>10],
        ['name'=>'nba直播','id'=>11],
     ];
    
    
    //利用管道
    Cache::getInstance()->pipeline();
    foreach ($words as $val) {
    
        $len = mb_strlen($val['name'],'utf-8');
        for ($i=0;$i<=$len;$i++){
    
            $key = mb_substr($val['name'],0,$i+1,'utf-8');
            if ($i == $len) {
                //所有相同关键词id
                $arr[$key][] = $val['id'];
    
                $key .= '*';
                //初始化关键词搜索次数
                Cache::getInstance()->hSet("search:hits",$key,0);
            }
            //分词加入有序集合
            Cache::getInstance()->zAdd('search',0,$key);
        }
    
    }
    Cache::getInstance()->exec();
    unset($words);
    
    //生成有用关键词hash表,用来存储id
    if (!empty($arr)) {
        array_walk($arr,function(&$v,$k){
            $v = join(',',$v);
        });
        Cache::getInstance()->hMset("search:ids",$arr);
    }
    
    echo 'ok';

    search.php

    <?php
    require './redis.php';
    
    $key = isset($_GET['key']) ? $_GET['key'] : 'nba直' ;
    
    //如果存在 自增1
    if (Cache::getInstance()->hGet("search:hits","{$key}*") !== false)
        Cache::getInstance()->hIncrBy("search:hits","{$key}*",1);
    
    //关键字开头存在有序集合的位置
    $index = Cache::getInstance()->zRank('search',$key);
    if ($index === false)
        goto END;
    
    
    if ($_res = Cache::getInstance()->zRange('search',$index,-1)){
    
        foreach ($_res as $val){
            if (strpos($val,$key) === 0 && strrev($val)[0] == '*'){
                $arr[] = substr($val,0,-1);
            }
        }
        //从hash表中获取id
        $res = Cache::getInstance()->hMGet("search:ids",$arr);
    
        //通过id 从mysql 获取数据源
        echo 'ok';
    }
    
    END:

     4. 前端ajax请求获取数据渲染模板

    完整代码: http://files.cnblogs.com/files/loveyouyou616/search.zip

      

  • 相关阅读:
    HDU 4348 To the moon(可持久化线段树)
    HDU 5875 Function 大连网络赛 线段树
    HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
    HDU 5876 大连网络赛 Sparse Graph
    HDU 5701 中位数计数 百度之星初赛
    CodeForces 708B Recover the String
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    ASP.NET生成验证码
    ASP.NET生成验证码
    ASP.NET生成验证码
  • 原文地址:https://www.cnblogs.com/loveyouyou616/p/5464112.html
Copyright © 2011-2022 走看看