From 937cdd5ad4dbee736d68a7a61cbca4dfab836a08 Mon Sep 17 00:00:00 2001
From: ztt <835303992@qq.com>
Date: Mon, 27 May 2024 15:58:52 +0800
Subject: [PATCH] 1

---
 app/command/SyncGoodsToEs.php               |   7 +-
 app/common/library/elasticsearch/Client.php | 602 +++++++++++++++++++-
 app/common/service/GoodsEs.php              |  39 +-
 config/console.php                          |   2 +-
 4 files changed, 620 insertions(+), 30 deletions(-)

diff --git a/app/command/SyncGoodsToEs.php b/app/command/SyncGoodsToEs.php
index 6255698c..136cfedf 100644
--- a/app/command/SyncGoodsToEs.php
+++ b/app/command/SyncGoodsToEs.php
@@ -2,7 +2,10 @@
 
 namespace app\command;
 
+use app\common\service\GoodsEs;
 use think\console\Command;
+use think\console\Output;
+use think\console\Input;
 
 class SyncGoodsToEs extends Command
 {
@@ -17,7 +20,9 @@ class SyncGoodsToEs extends Command
 
     protected function execute(Input $input, Output $output)
     {
-        $output->writeln('syncGoodsToEs');
+        $goodsService = new GoodsEs();
+        $goods = $goodsService->list([]);
+        var_dump($goods);
     }
 
 }
\ No newline at end of file
diff --git a/app/common/library/elasticsearch/Client.php b/app/common/library/elasticsearch/Client.php
index 0d84acf5..5c042c22 100644
--- a/app/common/library/elasticsearch/Client.php
+++ b/app/common/library/elasticsearch/Client.php
@@ -11,13 +11,34 @@ class Client
     const ES_HOST_NAME = '114.55.95.135:9200';
 
 
-    private static Client $instance;
+    private static  $instance;
 
-    private function __construct()
+    /**
+     * @var 索引名称
+     */
+    protected $index;
+
+
+    public $alias;
+
+    protected $retries = 2;
+
+    /**
+     * 查询参数
+     * @var array $queryParams
+     */
+    protected $queryParams = [];
+
+    private $debug;
+
+    public function __construct()
     {
+
+        var_dump(self::ES_HOST_NAME);
         $this->client = ClientBuilder::create()->setHosts([self::ES_HOST_NAME])->build();
     }
 
+
     private function __clone() {
 
     }
@@ -29,6 +50,81 @@ class Client
         return self::$instance;
     }
 
+    /**
+     * 查询条件
+     * @param $params
+     * @return $this
+     */
+    public function select($params = '')
+    {
+        $this->queryParams['select'] = str_replace(' ', '', trim($params, " ,\t\r\n"));
+        return $this;
+    }
+
+    /**
+     * 分页
+     * @param $number
+     * @return $this
+     */
+    public function from($number = 0)
+    {
+        $this->queryParams['from'] = $number ? ($number-1)*10 : 0;
+        return $this;
+    }
+
+    /**
+     * 页码
+     * @param $number
+     * @return $this
+     */
+    public function size($number = 10)
+    {
+        $this->queryParams['size'] = $number;
+        return $this;
+    }
+
+    public function equal($params = [])
+    {
+        $this->queryParams['equal'][] = $params;
+        return $this;
+    }
+
+    public function in($params = [])
+    {
+        $this->queryParams['in'][] = $params;
+        return $this;
+    }
+
+    public function like($params = [])
+    {
+        $this->queryParams['like'][] = $params;
+        return $this;
+    }
+
+    public function orlike($params = [])
+    {
+        $this->queryParams['orlike'][] = $params;
+        return $this;
+    }
+
+    public function order($params = [])
+    {
+        $this->queryParams['order'][] = $params;
+        return $this;
+    }
+
+    /**
+     * 根据条件删除文档
+     * @param array $params
+     * @return array
+     */
+
+    public function deleteDoc($params = [])
+    {
+        return $this->client->deleteByQuery($params);
+    }
+
+
     public function existsIndex(String $index_name) {
         $params = [
             'index' => $index_name
@@ -67,6 +163,182 @@ class Client
         return $this->client->indices()->delete($params);
     }
 
+    /**
+     * 根据id删除文档
+     * @param int $id
+     * @return array
+     */
+    public function deleteDocById($id = 0)
+    {
+        $params = [
+            'index' => $this->index,
+            'id' => $id
+        ];
+        $response = $this->client->delete($params);
+        return $response;
+    }
+
+    /**
+     * 组装查询条件
+     * @param array $params
+     * @return $this
+     */
+    private function parseQueryParams()
+    {
+        $queryParams = [
+            'index' => $this->index,
+            'body' => [
+                'query' => [
+                    'bool' => [
+                        'must' => [],
+                        'filter' => []
+                    ]
+                ]
+            ],
+            'from' => $this->queryParams['from'] ?? 0,
+            'size' => $this->queryParams['size'] ?? 10
+        ];
+
+        $filter = $must = [];
+        if (!empty($this->queryParams['select'])) {
+            $queryParams['_source'] = explode(',', $this->queryParams['select']);
+        }
+
+        if (!empty($this->queryParams['equal'])) {
+            foreach ($this->queryParams['equal'] as $key => $row) {
+                foreach ($row as $filed => $value) {
+                    $filter[] = [
+                        'term' => [$filed => $value]
+                    ];
+                }
+            }
+        }
+
+        if (!empty($this->queryParams['in'])) {
+            foreach ($this->queryParams['in'] as $key => $row) {
+                foreach ($row as $filed => $value) {
+                    $filter[] = [
+                        'terms' => [$filed => array_values(array_unique(array_filter($value)))]
+                    ];
+                }
+            }
+        }
+
+        if (!empty($this->queryParams['like'])) {
+            foreach ($this->queryParams['like'] as $key => $row) {
+                foreach ($row as $filed => $value) {
+                    /*$must[] = [
+
+                        'wildcard' => [$filed => '*'. $value. '*']
+
+                    ];*/
+                    $must[] = [
+//                        'match' => [$filed => $value]
+                        'match_phrase' => [$filed => $value]
+                    ];
+                }
+            }
+
+            $queryParams['body']['query']['bool']['must'] = $must;
+
+        }
+
+        if (!empty($this->queryParams['orlike'])) {
+            foreach ($this->queryParams['orlike'] as $key => $row) {
+                foreach ($row as $filed => $value) {
+                    $orlike[] = [
+                        'match_phrase' => [$filed => $value]
+                    ];
+                }
+            }
+
+            $queryParams['body']['query']['bool']['must']['bool']['should'] = $orlike;
+        }
+
+        if (!empty($this->queryParams['order'])) {
+            $queryParams['body']['sort'] = [
+                key($this->queryParams['order']) => [
+                    'order' => current($this->queryParams['order'])
+                ]
+            ];
+        }
+
+        $queryParams['body']['query']['bool']['filter'] = $filter;
+
+        $this->queryParams = $queryParams;
+
+        return $this;
+
+    }
+
+
+    /**
+     * @param bool $isTotal isTotal=true时, 返回总数
+     * @return array|string
+     */
+
+    public function query($isTotal = false)
+    {
+        try {
+            $this->parseQueryParams();
+
+            if ($this->debug) {
+                return \GuzzleHttp\json_encode($this->queryParams);
+            }
+
+            if ($isTotal === true) {
+
+                unset(
+
+                    $this->queryParams['from'],
+
+                    $this->queryParams['size'],
+
+                    $this->queryParams['_source']
+
+                );
+
+                $count = $this->client->count($this->queryParams);
+
+                return (int)$count['count'];
+
+            }
+
+            if (!empty($this->queryParams)) {
+
+                $result = $this->client->search($this->queryParams);
+
+                if (!empty($result['hits']['hits'])) {
+
+                    $return = [];
+
+                    foreach ($result['hits']['hits'] as $row) {
+
+                        $return[] = $row['_source'];
+
+                    }
+
+                    return $return;
+
+                } else {
+
+                    return [];
+
+                }
+
+            }
+
+        } catch (\Exception $e) {
+
+            $msg = $e->getMessage();
+
+            $msg = '服务器开小差了~';
+
+            throw new Exception($msg);
+
+        }
+    }
+
     /**
      * 添加文档
      * @param $id
@@ -86,6 +358,36 @@ class Client
         return $this->client->index($params);
     }
 
+    public function getIndex()
+    {
+        return $this->index;
+    }
+
+    /**
+     * 返回ES实例
+     */
+
+    public static function setEs($index = '')
+    {
+        $class = get_called_class();
+        if (!self::$instance || !self::$instance instanceof $class) {
+            self::$instance = new static();
+        }
+        if ($index) {
+            self::$instance->index = $index;
+        }
+        return self::$instance;
+
+    }
+
+    protected function settings()
+    {
+        return [
+            'number_of_shards' => 1,
+            'number_of_replicas' => 0
+        ];
+    }
+
     /**
      * 判断文档存在
      * @param int $id
@@ -144,40 +446,306 @@ class Client
         return $this->client->update($params);
     }
 
+
     /**
-     * 删除文档
-     * @param int $id
+     * 搜索文档:分页,排序,权重,过滤
      * @param string $index_name
      * @param string $type_name
+     * @param array $body
      * @return array
      */
-    public function deleteDoc(int $id = 1, string $index_name = 'gyx_ik', string $type_name = '_doc'): array
+    public function searchDoc(array $body = [], string $index_name = "goods_list", string $type_name = "_doc"): array
     {
         $params = [
             'index' => $index_name,
             'type' => $type_name,
-            'id' => $id
+            'body' => $body
         ];
 
-        return $this->client->delete($params);
+        return $this->client->search($params);
+    }
+
+    /**
+
+     * @return bool
+
+     * @throws Exception
+
+     */
+
+    public function createIndexNew($mapping)
+    {
+        try {
+            $params = [
+                'index' => $this->index
+            ];
+
+            $check = $this->indices()->exists($params);
+
+            if ($check) {
+                throw new Exception('index: ' . $this->index . ' already exists');
+            }
+
+            $params = [
+                'index' => $this->index,
+                'body' => [
+                    'settings' => $this->settings(),
+                    'mappings' => [
+                        '_source' => [
+                            'enabled' => true,
+                        ],
+                        'properties' => $mapping
+                    ]
+                ]
+            ];
+
+            $result = $this->indices()->create($params);
+
+            return $result['acknowledged'] === true;
+
+        } catch (\Exception $e) {
+
+            throw new Exception($e->getMessage());
+
+        }
+
     }
 
+    /**
+
+     * 删除索引
+
+     *
+
+     * @return bool
+
+     * @throws Missing404Exception
+
+     */
+
+    public function deleteIndexNew()
+    {
+
+        try {
+
+            $params = [
+
+                'index' => $this->index
+
+            ];
+
+            $check = $this->indices()->exists($params);
+
+            if (!$check) {
+
+                return true;
+
+            }
+
+            $result = $this->indices()->delete([
+
+                'index' => $this->index
+
+            ]);
+
+            return $result['acknowledged'] === true;
+
+        } catch (Missing404Exception $e) {
+
+            throw new Missing404Exception('no such index ' . $this->index);
+
+        }
+
+    }
 
     /**
-     * 搜索文档:分页,排序,权重,过滤
-     * @param string $index_name
-     * @param string $type_name
-     * @param array $body
-     * @return array
+
+     * 批量写入
+
+     * type 1.增加/修改 2.删除
+
+     * $data = [
+
+     *      ['id' => 1, 'name' => 'llf', 'age' => 30],
+
+     *      ['id' => 1, 'name' => 'llf', 'age' => 30],
+
+     *      ['id' => 1, 'name' => 'llf', 'age' => 30],
+
+     *      ['id' => 1, 'name' => 'llf', 'age' => 30],
+
+     * ];
+
+     * @param array $data
+
+     */
+
+    public function doBulkDocument($type = 1,$data = [])
+
+    {
+
+        try {
+
+            $params = ['body' => []];
+
+            if($type == 1){
+
+                foreach ($data as $key => $row) {
+
+                    $params['body'][] = [
+
+                        'index' => [
+
+                            '_index' => $this->index,
+
+                            '_id' => $row['info_id'].'-'.$row['info_type']
+
+                        ]
+
+                    ];
+
+                    $params['body'][] = $row;
+
+                    if (($key+1)%10000 == 0) {
+
+                        $this->client->bulk($params);
+
+                        $params = ['body' => []];
+
+                    }
+
+                }
+
+            }else{
+
+                foreach ($data as $key => $row) {
+
+                    $params['body'][] = [
+
+                        'delete' => [
+
+                            '_index' => $this->index,
+
+                            '_id' => $row['info_id'].'-'.$row['info_type']
+
+                        ]
+
+                    ];
+
+                }
+
+            }
+
+            if (!empty($params['body'])) {
+
+                $this->client->bulk($params);
+
+                return true;
+
+            }
+
+        } catch (\Exception $e) {
+
+            throw new Exception($e->getMessage());
+
+        }
+
+    }
+
+    /**
+
+     * @return array @todo
+
      */
-    public function searchDoc(array $body = [], string $index_name = "gyx_ik", string $type_name = "_doc"): array
+
+    public function updateIndex()
+
     {
+
+        $putParams = [
+
+            'index' => $this->index,
+
+            //'type' => '_doc',
+
+            'body' => [
+
+                'properties' => $this->mappings()
+
+            ]
+
+        ];
+
+        return $this->indices()->putMapping($putParams);
+
+    }
+
+    /**
+
+     * 方便调试, 直接返回拼接的query
+
+     * @return $this
+
+     */
+
+    public function setDebug()
+
+    {
+
+        $this->debug = true;
+
+        return $this;
+
+    }
+
+    private function indices()
+
+    {
+
+        return $this->client->indices();
+
+    }
+
+    public function analyze($text = '')
+
+    {
+
         $params = [
-            'index' => $index_name,
-            'type' => $type_name,
-            'body' => $body
+
+            'index' => $this->index,
+
+            'body' => [
+
+                'analyzer' => 'ik_smart',
+
+                'text' => $text
+
+            ]
+
         ];
 
-        return $this->client->search($params);
+        return $this->indices()->analyze($params);
+
+    }
+
+    public function update($id = 0, $updateParams = [])
+
+    {
+
+        $params = [
+
+            'index' => $this->index,
+
+            'id' => $id,
+
+            'body' => [
+
+                'doc' => $updateParams
+
+            ]
+
+        ];
+
+        return $this->client->update($params);
     }
 }
diff --git a/app/common/service/GoodsEs.php b/app/common/service/GoodsEs.php
index 8e6f6233..f5106e6f 100644
--- a/app/common/service/GoodsEs.php
+++ b/app/common/service/GoodsEs.php
@@ -8,9 +8,11 @@ class GoodsEs
 {
     private Client $esService;
 
+    private $index_name = 'goods_list';
+
     public function __construct()
     {
-        $this->esService = Client::getInstance();
+        $this->esService = Client::setEs('goods_List');
     }
 
     /**
@@ -34,7 +36,13 @@ class GoodsEs
                 ]
             ]
         ];
-        return $this->esService->searchDoc($body);
+
+        return $this->esService
+            ->equal(['title' => 1])
+            ->from(0)
+            ->size(10)
+            ->order(['id' => 'desc'])
+            ->query($body);
     }
 
 
@@ -43,7 +51,7 @@ class GoodsEs
     /**
      * 更新商品
      */
-    public function updateDoc($goods_id)
+    public function update($goods_id)
     {
         $goods_id = 1;
         $doc = [
@@ -61,12 +69,22 @@ class GoodsEs
         var_dump($res);
     }
 
+    /**
+     * 查询商品详情
+     */
+    public function detail($goods_id)
+    {
+        $goods_id = 1;
+        $res = $this->esService->getDoc($goods_id);
+        var_dump($res);
+    }
+
 
     /**
      * 创建商品
      * @return
      */
-    public function createDoc($goods_id)
+    public function create($goods_id)
     {
         $goods_id = 1;
         $doc = [
@@ -87,7 +105,7 @@ class GoodsEs
     /**
      * 删除商品
      */
-    public function deleteDoc($goods_id)
+    public function delete($goods_id)
     {
         $res = $this->esService->deleteDoc($goods_id);
         var_dump($res);
@@ -104,12 +122,11 @@ class GoodsEs
     {
         $mapping = [
             'properties' => [
-                'id' => [
-                    'type' => 'keyword'
+                'goods_id' => [
+                    'type' => 'integer'
                 ],
-                'video_title' => [
-                    'type' => 'text',
-                    "analyzer" => "ik_smart"
+                'goods_type' => [
+                    'type' => 'keyword'
                 ],
                 'director' => [
                     'type' => 'text',
@@ -137,7 +154,7 @@ class GoodsEs
             ]
         ];
 
-        $res = $this->esService->createIndex('video_list', $mapping);
+        $res = $this->esService->createIndex($this->index_name, $mapping);
         var_dump($res);
     }
 
diff --git a/config/console.php b/config/console.php
index dbcf36f3..09465dc3 100644
--- a/config/console.php
+++ b/config/console.php
@@ -12,6 +12,6 @@ return [
         'CalDealerTime' => 'app\command\CalDealerTime',
         'UpdateCollectGoodsPrice' => 'app\command\UpdateCollectGoodsPrice',
         'SyncStoreBasicData' => 'app\command\SyncStoreBasicData',
-        'syncGoodsToEs' => 'app\command\syncGoodsToEs',
+        'syncGoodsToEs' => 'app\command\SyncGoodsToEs',
     ],
 ];