Elasticsearch 在PHP中运用

本文介绍了一种基于Elasticsearch的同步机制实现方法,通过ESModel类实现数据从数据库到Elasticsearch的同步,包括创建、更新和删除索引等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需要同步的配置文件

<?xml version="1.0" encoding="utf-8"?>
<chi_index number_of_shards="1" number_of_replicas="0">
    <BaseInfo>
        <field tag="eng"   type="string"  index="mix">B040022</field>
        <field tag="ip"    type="integer" index="not_analyzed" doc_values="false">F020004</field>
        <field tag="mac"   type="keyword"  index="not_analyzed" doc_values="false">C040002</field>
        <field tag="date"  type="integer"    index="not_analyzed">H010014</field>
        <field tag="int"   type="integer" index="not_analyzed" doc_values="false">F020006</field>
        <field tag="code"  type="keyword"  index="not_analyzed" doc_values="false">F010008</field>
    </BaseInfo>
    <MobileInfo>
        <field tag="code" type="string"  index="not_analyzed" doc_values="false">C020017</field>
        <field type="string"  index="analyzed">C020011</field>
        <field type="keyword"  index="not_analyzed">C050001</field>
        <field type="keyword"  index="not_analyzed" doc_values="false">Z118003</field>
        <field tag="mac" type="keyword"  index="not_analyzed" doc_values="false">Z118004</field>
    </MobileInfo>
    <index name="TTest" cycle="mouth">
        <map name="TTest" mobile="false">
            <field tag="eng"  type="string"  index="mix">Z118011</field>
        </map>
    </index>

    <index name='TTests' cycle="year">
        <map name="TTests1" mobile="true">
            <field type="keyword" index="not_analyzed">B050004</field>
            <field tag="code" type="keyword" index="not_analyzed" doc_values="false">H010003</field>
        </map>
        <map name="TTests2" mobile="true">
            <field type="keyword" index="not_analyzed">B040002</field>
            <field tag="code" type="keyword" index="not_analyzed" doc_values="false">H010003</field>
        </map>
    </index>
</chi_index>

操作es的基础方法

什么时候使用ESModel?
目前的操作方法是需要使用ES搜索引擎的数据,才同步到ES中去,那么添加一条数据到db中,则需要将添加的这条数据,同步到es中,目前使用的同步是调用ESModel中的 index() 方法。

namespace App\Services;
use Elasticsearch\ClientBuilder;
class ESModel
{
    //Elasticsearch Client Object
    private $client;
    //需要同步的数据库
    private $index;
    //需要同步的表
    private $types;
    //各表需要同步的字段
    private $fields;

    /**
     * ES constructor.
     */
    public function  __construct(){
        $connectionPool = '\Elasticsearch\ConnectionPool\StaticNoPingConnectionPool';
        $server_ip = env('DB_HOST');
        $hosts = [
            "$server_ip:9200"
        ];
        // Instantiate a new ClientBuilder
        $this->client = ClientBuilder::create()
            ->setConnectionPool($connectionPool)
            ->setHosts($hosts)      // Set the hosts
            ->build();
//        dd($this->client );

        //读取需要同步的索引字段
        $path = storage_path();
        $xml_path = $path.'/config/chi_index.xml';
        $xml_array = simplexml_load_file($xml_path);
        //$index = $xml_array->index->attributes()['name'];
        //需要同步的数据库
        //$this->index = strtolower($index);
        foreach($xml_array->index as $table){
            $type = $table->attributes()['name'];
//            $types[] = "$type";
            foreach ($table->map as $map) {
                $maps = $map->attributes()['name'];
                $map_tmp = "$maps";
                $types[]  = $map_tmp;
                $index_name[$map_tmp] = "$type";
                foreach ($map->field as $field) {
                    if($field->attributes()['name'] != null){
                        $type_child = $field->attributes()['name'];
                        foreach($field->child as $child){
    //                            var_dump($type_child);
    //                            var_dump($child);
                            $fields["$type"][] = $type_child.".".$child;
                        }
                    } else {
                        $fields[$map_tmp][] = "$field";
                    }
                }
            }

        }

        //需要同步的index
        $this->index = $index_name;
        //需要同步的表
        $this->types = $types;
        //各张表需要同步的字段
        $this->fields = $fields;
    }


    /**
     * 创建或更新索引--单条
     * @param $table
     * @param $data
     * @param $id
     * @return string
     */
    public function index($table, $data, $id){
//
        if (!in_array($table, $this->types)) return "no need to build index for table $table";

        $params = array();
        $index_arr = $this->index;
        $index = strtolower($index_arr[$table]);
        $year = '';
        if($index != 'tqqcatched' || $index != 'tbasedata') {
            $year = date("Y",time());
        }
        $params['index'] = $index.$year;
        $params['type'] = strtolower($table);
//        $table = strtolower($table);
//        dd( $this->fields);
        foreach ($data as $key => $value) {
//            var_dump($key);
//            var_dump($this->fields);
            if ($key == '_id') {
                $params['_id'] = $value;
            } else if (in_array($key, $this->fields[$table])) {
                //过滤不需要建索引的字段
                $params['body'][$key] = $value;
            }
        }

        $id ? ($params['_id'] = $id) : null;

        try{
            $res = $this->client->index($params);
            return $res;
        } catch (\Exception $e) {
            return 'error:' . $e->getMessage();
        }

    }

    /**
     * 更新索引
     * @param $table 集合名
     * @param $data 更新字段数据
     * @param $id 值
     * @return array|bool
     */
    public function update($table, $data, $id){
        if (!$id) return '$id is empty!';
//        $table = strtolower($table);
        if (!in_array($table, $this->types)) return "no need to build index for table $table";
        $params = array();
        $index_arr = $this->index;

        $index = strtolower($index_arr[$table]);
        $year = '';
        if($index != 'tqqcatched' && $index != 'tbasedata') {
            $year = date("Y",time());
        }
        $params['index'] = $index.$year;
        $params['type'] = strtolower($table);
        $params['_id'] = $id;

        foreach ($data as $key => $value) {
            if ($key == '_id') {
                $params['_id'] = $value;
            } else if (in_array($key, $this->fields[$table])) {
                //过滤不需要建索引的字段
                $params['body']['doc'][$key] = $value;
            }
        }
        //没有索引
        if(!isset($params['body']['doc'])){
            return true;
        }
        try{
            $res = $this->client->update($params);
            return $res;
        } catch (\Exception $e) {
            return 'error:' . $e->getMessage();
        }

    }
    //删除索引
    public function delete($table, $id){
        if (!$id) return '$id is empty!';
        $table = strtolower($table);
        if (!in_array($table, $this->types)) return "no need to build index for table $table";

        $params = array();
        $params['index'] = $this->index;
        $params['type'] = $table;
        $params['id'] = $id;

        try{
            $res = $this->client->delete($params);
        } catch (Exception $e) {
            return 'error:' . $e->getMessage();
        }

        return $res;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值