Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can you publish a document website #58

Open
Fsternal opened this issue Nov 16, 2022 · 1 comment
Open

Can you publish a document website #58

Fsternal opened this issue Nov 16, 2022 · 1 comment
Labels
question Further information is requested

Comments

@Fsternal
Copy link

Because some test cases and documents on github are not clear, such as how to create indexes and use geo search, and which methods should be used to create indexes for some common database types😁
Because I'm not familiar with redissearch now
I believe there will be others like me

Thanks♪(・ω・)ノ

@MacFJA MacFJA added the question Further information is requested label Dec 1, 2022
@itmeicn
Copy link

itmeicn commented Dec 3, 2022

CommonPhprediSearch.php

<?php
/**
 *使用Phpredis插件连接redis,rediSearch公用方法
 * composer remove  macfja/redisearch
 * composer require macfja/redisearch
 * @date 8:35
 */

namespace app\common\search;

use app\common\traits\JumpReturn;
use MacFJA\RediSearch\Redis\Client\ClientFacade;
use MacFJA\RediSearch\Redis\Command\IndexList;
use Redislabs\Module\ReJSON\ReJSON;
use think\Model;

class CommonPhprediSearch extends Model
{
    use JumpReturn;
    private $nativeRedis;//php自带的phpRedis插件初始化
    public $clientPhprearch;//init rediSearch using Predis
    public $clientJson;//初始化 redisJson
    public $initSearch;//init  search
    public $indexList;//索引列表
    public function __construct(array $data = [])
    {
        parent::__construct($data);
        //获取连接redis句柄 开始
        $this->nativeRedis=(new \Redis());//
        $config=config('cache.stores.redis');
        $this->nativeRedis->connect($config['host'],$config['port']);
        $this->nativeRedis->auth($config['password']);
        $this->nativeRedis->select(0);
        //获取连接redis句柄 结束
        //dump($this->nativeRedis);
        $clientFacade=new ClientFacade();//引用rediSearch
        $this->clientPhprearch=$clientFacade->getClient($this->nativeRedis);//初始化rediSearch
        //dump($this->clientPhprearch);
        $this->clientJson=ReJSON::createWithPhpRedis($this->nativeRedis);//初始化redisJson
        //初始化rediSearch中的搜索类
        $this->initSearch=new \MacFJA\RediSearch\Redis\Command\Search(\MacFJA\RediSearch\Redis\Initializer::getRediSearchVersion($this->clientPhprearch));

    }
    /**
     *显示创建的索引详情内容
     * @param string $indexName 索引名
     **/
    public function mShowIndexInfo($indexName)
    {
        try {
            $this->nativeRedis->setOption(8,true);
            $res=$this->nativeRedis->rawCommand('ft.info',$indexName);
            return $this->retArray('ok',200,$res);
        }catch (\RedisException $e){

            return $this->retArray($e->getMessage(),300);
        }

    }
    /**
     * 返回search公共返回函数,控制层接收数据用
     * @param string $message 提示
     * @param int $code 200:正确,300:错误
     * @param array $data 内容
     * @return array
     */
    protected function retArray($message,$code,$data=[]){
        return ['code'=>$code,'message'=>$message,'data'=>$data];
    }

    /**
     *使用原生语句 删除数据
     * @param string $name redis变量名
     */
    public function mDelOnlyData($name)
    {
        $list=$this->nativeRedis->keys($name);
        foreach ($list as $v) {
            $this->nativeRedis->del($v);
        }
        return 1;
    }
    /**
     * 检测索引是否被创建
     * @param string $name redis变量名
     */
    public function getIndex($name){
        $indexList=$this->clientPhprearch->execute(new IndexList());
        $this->indexList=$indexList;
        if(in_array($name,$indexList)){
            return true;
        }else{
            return false;
        }
    }
    /**
     * 构建 数据字段
     */
    public function setField(){

    }

}

AdminSearch.php

<?php
/**
 *
 * @author [email protected]
 * @date 9:07
 */

namespace app\common\search;

class AdminSearch extends CommonPhprediSearch
{
    protected $name='admin';
    private $redisField;//redis数据表字段

    public function __construct(array $data = [])
    {
        parent::__construct($data);
        //rediSearch只有4只属性,text:文本,tag:精确匹配查询,例如类别或主键,numeric:标识所有数字类型(范围查询),geo:经度(第一)和纬度的字符串(以逗号分隔),VECTOR:http://mis.univoa.com/article/i/50#gui-mlink-5
        //存放到redis的时间,以时间戳格式,便于排序,此书字段必须和数据库字段一查一样(这里是模拟数据,有些字段没配)
        //创建索引、添加内容的字段顺序,一定要和$this->redisField一模一样,错行或顺序错误会导致rediSearch出错

     $this->redisField=['id'=>['defaults'=>0],'userid'=>['defaults'=>''],'username'=>['defaults'=>''],'status'=>['defaults'=>2],'login_ip'=>['defaults'=>''],
         'login_time'=>['defaults'=>0],'token'=>['defaults'=>''],'mobile'=>['defaults'=>''],'create_time'=>['defaults'=>time()],'coid'=>['defaults'=>''],
             'shortcode'=>['defaults'=>''],'pushid'=>['defaults'=>''],'kaoqin_remaind'=>['defaults'=>0],'telephone_number'=>['defaults'=>''],'main_depart'=>['defaults'=>0]];

    }

    /**
     *创建索引
     **/
    public function mCreateIndex()
    {
        try {
            //先判断是否存在,code==200存在就先删除,不存在就直接创建
            ////此书字段必须和数据库字段一查一样(这里是模拟数据,有些字段没配),
            $isIndex=$this->mShowIndexInfo($this->name.'Idx');
            if ($isIndex['code']==200){
                $this->mDelIndexName();//删除存在的索引
            }
            $builder=new \MacFJA\RediSearch\IndexBuilder();
//use  redisJson saved data
            $res=$builder->setIndex($this->name.'Idx')->setStructure('JSON')->addPrefixes($this->name.':')
                ->setDefaultLanguage('chinese')
                ->addJSONNumericField('$.id','id',true)
                ->addJSONTextField('$.userid','userid',false,10,null,true)
                ->addJSONTextField('$.username','username',false,8,null,true)
                ->addJSONNumericField('$.status','status',true)
                ->addJSONTextField('$.login_ip','login_ip')
                ->addJSONNumericField('$.login_time','login_time')
                ->addJSONTextField('$.token','token',false,6)
                ->addJSONTextField('$.mobile','mobile')
                ->addJSONTextField('$.create_time','create_time',false,null,null,true)
                 ->addJSONTextField('$.coid','coid',false,null,null,true)
                 ->addJSONTextField('$.shortcode','shortcode',false,4,null,true)
                 ->addJSONTextField('$.pushid','pushid')
                 ->addJSONNumericField('$.kaoqin_remaind','kaoqin_remaind')
                 ->addJSONTextField('$.telephone_number','telephone_number')
                 ->addJSONNumericField('$.main_depart','main_depart',true)
                ->create($this->clientPhprearch,\MacFJA\RediSearch\Redis\Initializer::getRediSearchVersion($this->clientPhprearch));
            if ($res){
                return self::JsonReturn('创建索引成功',200);
            }else{
                return self::JsonReturn('创建索引失败请重试',300);
            }
        }catch (\RedisException $e){
            return self::JsonReturn('错误:'.$e->getMessage(),300);
        }
    }
    /**
     *列表
     **/
    public function mList($h=[])
    {
        if ($h){
            //自己写搜索
        }else{
            //默认搜索全部
            $where='*';
        }
        //排序
        $sort='id';//排序字段
        $order='DESC';//ASC|DESC

        $search=$this->initSearch->setIndex($this->name.'Idx')->setLanguage('chinese')
            ->setQuery($where)->setSortBy($sort,$order)->setLimit(PAGE-1,LIMIT)
           ;
        $result=$this->clientPhprearch->execute($search);//返回类 src/Redis/Response/PaginatedResponse.php
        $count=$result->getTotalCount();//总记录数
        $listPage=$result->current();//获取当前页,返回类 src/Redis/Response/SearchResponseItem.php
        $list=[];//真实的数据
        foreach ($listPage as $li){
            $temp=$li->getFields();//获取字段数组,getHash()定义的redis名称
            $list[]=$temp;
        }
        unset($listPage);
        return self::ajaxResult($count,$list);
    }

    /**
     *测试
     */
    public function mTest()
    {
        $res=$this->clientJson->mget('doc1','doc2','$..a');
        return $res;
    }
    /**
     *添加
     **/
    public function mAdd($h)
    {
       // $h=['userid'=>'12345','username'=>'奥特曼'];

        //先校验数据
        try {
            $h['create_time']=date('Y-m-d H:i:s');//创建时间
            self::startTrans();
            //mysql添加表
            $isId=self::insertGetId($h);
            //把用到的值都设置好默认值
            $h['id']=$isId;
            //这里再校验redisFields,如果不存的字段默认设置
            unset($h['create_time']);//这里删除是因为,redisSearch的时间只认时间戳
            $insertRedis=[];//写入redis
            foreach ($this->redisField as $k=>$v){
                $insertRedis[$k]=isset($h[$k])?$h[$k]:$v['defaults'];
            }
            try {
                $this->clientJson->set($this->name.':'.$isId,'$',$insertRedis);
            }catch (\RedisException $e){
                throw new \think\Exception('写入内存失败,请重试或联系技术部');
            }

            self::commit();
            return self::JsonReturn('添加成功',200);


        }catch (\Exception $e){
            self::rollback();
            return self::JsonReturn('错误:'.$e->getMessage(),300);
        }
    }


    /** update data
     * @param  array $h
     **/
    public function mUpdate($h)
    {
        //先校验数据

        try {
            self::startTrans();
            //mysql表内容修改
            $res1=self::update($h);
            //redis修改内容
            if ($res1){
                try {
                    //判断$h只允许保存定义中的变量写入redis
                    $allowfields=array_keys($this->redisField);
                    foreach ($h as $k=>$v){
                        if (in_array($k,$allowfields)){
                            $this->clientJson->set($this->name.':'.$v['id'],'$.'.$k,$v);
                        }

                    }
                }catch (\RedisException $e){
                    throw new \think\Exception('编辑内存数据失败,请重试或联系技术部');
                }
            }
            self::commit();
            return self::JsonReturn('更新成功',200);

        }catch (\Exception $e){
            self::rollback();
            return self::JsonReturn('错误:'.$e->getMessage(),300);
        }
    }
    /**
     * 删除单条或多条记录
     * @param $ids
     * @return \think\response\Json
     */
    public function mDel($ids){
        $index=new \MacFJA\RediSearch\Index($this->name.'Idx',$this->clientPhprearch);
        try {
            self::startTrans();
            if (is_array($ids)){
                $id=$ids;
            }else{
                $id=explode(",",$ids);
            }
            try {
                foreach ($id as $v){
                    //使用rediSearch删除记录
                    $index->deleteDocument($this->name.':'.$v);
                }
            }catch (\RedisException $e){
                throw new \Exception('删除时Redis内存错误,请重试');
            }
            $result = self::where('id', 'in',$id)->delete();

            if ($result) {
                self::commit();
                return self::JsonReturn("删除成功",200);
            } else {
                throw new \Exception('删除失败,请重试');
            }
        } catch (\Exception $e) {
            self::rollback();
            return self::JsonReturn($e->getMessage(),300);
        }
    }

    /**
     *删除索引或删除索引同时也把所有的数据删除
     * @param boolean $deleteDocument false删除索引true删除索引和数据
     **/
    public function mDelIndexName($deleteDocument=false)
    {
        try {
            $index=new \MacFJA\RediSearch\Index($this->name.'Idx',$this->clientPhprearch);
            $result=$index->delete($deleteDocument);
            if ($result) {

                return self::JsonReturn("删除索引成功",200);
            } else {
                return self::JsonReturn("删除索引失败,请重试或联系技术部",300);
            }
        }catch (\RedisException $e){
            return self::JsonReturn($e->getMessage(),300);
        }
    }

    /**
     *把mysql的数据导入redis
     * @param array $list
     **/
    public function mMysqlToRedis()
    {
        try {
            if ($this->redisField){
                $fields=implode(',',array_keys($this->redisField));
            }else{
                return self::JsonReturn('必须在Search层定义RedisField',300);
            }
            //导入时,先删除之前存在的记录(原生redis语法删除)
            $this->mDelOnlyData($this->name.':*');
            //dump($fields);exit();
            $list=self::where('status','in',[1,2])
                ->field($fields)
                ->select()->toArray();
            foreach ($list as $v){
                //ReJSON::createWithPhpRedis($this->nativeRedis);
                $this->clientJson->set($this->name.':'.$v['id'],'$',$v);
            }
            return self::JsonReturn("写入Redis成功",200);
        }catch (\Exception $e){
            return self::JsonReturn($e->getMessage(),300);
        }
    }


}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants