From 1cfe0989642aded104d7abdef4c96cc7ac7214f1 Mon Sep 17 00:00:00 2001 From: ztt <835303992@qq.com> Date: Fri, 14 Jun 2024 00:08:45 +0800 Subject: [PATCH] =?UTF-8?q?ES=E6=9F=A5=E8=AF=A2DEMO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/controller/GoodsNew.php | 32 +- app/command/SyncGoodsToEs.php | 10 +- app/common/library/elasticsearch/Client.php | 193 +++++-- app/common/service/GoodsCateEs.php | 533 ++++++++++++++++++++ 4 files changed, 723 insertions(+), 45 deletions(-) create mode 100644 app/common/service/GoodsCateEs.php diff --git a/app/api/controller/GoodsNew.php b/app/api/controller/GoodsNew.php index aac7c3ea..3377f8cf 100644 --- a/app/api/controller/GoodsNew.php +++ b/app/api/controller/GoodsNew.php @@ -3,6 +3,8 @@ namespace app\api\controller; +use app\common\model\GoodsCategoryRel; +use app\common\service\GoodsCateEs; use app\common\service\GoodsEs; use think\App; @@ -23,9 +25,16 @@ class GoodsNew extends Controller if (!$keyword) { $this->renderError('请输入搜索关键字'); } - $params = ['goods_name' => $keyword]; - $goodsService = new GoodsEs(); - $list = $goodsService->list($params, $page, $limit); + $params = ['goods_name' => $keyword, 'status' => 10]; + + //限制过滤条件-渠道 + $params['channels'] = $this->storeInfo['open_channel'] ? array_merge(['zy'], explode(",", $this->storeInfo['open_channel'])) : []; + //分类利润-利润率 + $params['fliter_condition'] = $this->storeInfo['fliter_condition']; + + + $goodsService = new GoodsCateEs(); + $list = $goodsService->list( $params, $page, $limit); $data['list'] = $list; $data['total'] = $goodsService->count($params); @@ -43,11 +52,26 @@ class GoodsNew extends Controller ->order('goods_id desc') ->find() ->toArray(); - $goodsService = new GoodsEs(); + $goodsService = new GoodsCateEs(); $data = $goodsService->createData($goods_id, $goods_data); $this->renderSuccess($data); } + /** + * 创建分类 + */ + public function create() + { + $cate_id = 1; + $cate_data = GoodsCategoryRel::where('goods_id', '=', $cate_id) + ->order('id desc') + ->find() + ->toArray(); + $goodsService = new GoodsCateEs(); + $data = $goodsService->createCateData($cate_id, $cate_data); + $this->renderSuccess($data); + } + /** * 更新商品 */ diff --git a/app/command/SyncGoodsToEs.php b/app/command/SyncGoodsToEs.php index c952729e..2cc2fd66 100644 --- a/app/command/SyncGoodsToEs.php +++ b/app/command/SyncGoodsToEs.php @@ -2,6 +2,7 @@ namespace app\command; +use app\common\service\GoodsCateEs; use app\common\service\GoodsEs; use think\console\Command; use think\console\Output; @@ -20,9 +21,12 @@ class SyncGoodsToEs extends Command protected function execute(Input $input, Output $output) { - $goodsService = new GoodsEs(); - $goods = $goodsService->list(); - var_dump($goods); + $goodsService = new GoodsCateEs(); + try { + $goodsService->batchCreateData(); + }catch (\Exception $e) { + $output->writeln($e->getMessage()); + } } } \ No newline at end of file diff --git a/app/common/library/elasticsearch/Client.php b/app/common/library/elasticsearch/Client.php index 9af6eb96..3fa0e21e 100644 --- a/app/common/library/elasticsearch/Client.php +++ b/app/common/library/elasticsearch/Client.php @@ -81,18 +81,42 @@ class Client return $this; } + /** + * 批量查询 + * @param $params + * @return $this + */ public function equal($params = []) { $this->queryParams['equal'][] = $params; return $this; } + /** + * 批量查询 + * @param $params + * @return $this + */ public function in($params = []) { $this->queryParams['in'][] = $params; return $this; } + /** + * 范围查找 + */ + public function between($params = []) + { + $this->queryParams['between'] = $params; + return $this; + } + + /** + * 模糊查询 + * @param $params + * @return $this + */ public function like($params = []) { $this->queryParams['like'][] = $params; @@ -105,6 +129,28 @@ class Client return $this; } + /** + * has_parent 查询(父查子) + * @param $params + * @return $this + */ + public function hasParent($params = []) + { + $this->queryParams['has_parent'][] = $params; + return $this; + } + + /** + * has_child 查询(子查父) + * @param $params + * @return $this + */ + public function hasChild($params, $child_params = []) + { + $this->queryParams['has_child'] = $params; + return $this; + } + public function order($params = []) { $this->queryParams['order'][] = $params; @@ -199,7 +245,7 @@ class Client ]; - $filter = $must = []; + $filter = $must = $orFilter = []; if (!empty($this->queryParams['select'])) { $queryParams['_source'] = explode(',', $this->queryParams['select']); } @@ -255,6 +301,71 @@ class Client $queryParams['body']['query']['bool']['must']['bool']['should'] = $orlike; } + //has_child 查询(子查父) + if (!empty($this->queryParams['has_child'])) { + $should = []; + foreach ($this->queryParams['has_child'] as $key => $row) { + $queryMust = []; + foreach ($row as $name => $value) { + if ($name == 'category_id') { + $queryMust[] = [ + 'has_child' => [ + 'type' => 'category', + 'query' => [ + 'bool' => [ + 'must' => [ + 'terms' => [ + 'category_id' => $value + ] + ] + ] + ], + ], + ]; + } + if ($name == 'profit') { + $queryMust[] = [ + 'range' => [ + 'profit' => [ + 'gte' => $value, + ] + ] + ]; + } + + if ($name == 'profit_rate') { + $queryMust[] = [ + 'range' => [ + 'profit_rate' => [ + 'gte' => $value, + ] + ] + ]; + } + } + $should[] = [ + 'bool' => [ + 'must' => $queryMust + ] + ]; + } + $filter[] = [ + 'bool' => [ + 'should' => $should + ] + ]; + } + + //has_parent 查询(父查子) + if (!empty($this->queryParams['has_parent'])) { + foreach ($this->queryParams['has_parent'] as $key => $row) { + $queryParams['body']['query']['bool']['must'][] = [ + 'has_parent' => $row + ]; + } + } + + if (!empty($this->queryParams['order'])) { foreach ($this->queryParams['order'] as $key => $row) { $queryParams['body']['sort'][] = [ @@ -281,7 +392,7 @@ class Client public function query($isTotal = false) { - try { +// try { $this->parseQueryParams(); // dd($this->queryParams); @@ -333,15 +444,15 @@ class Client } - } catch (\Exception $e) { - - $msg = $e->getMessage(); - - $msg = '服务器开小差了~'; - - throw new Exception($msg); - - } +// } catch (\Exception $e) { +// +// $msg = $e->getMessage(); +// +// $msg = '服务器开小差了~'; +// +// throw new Exception($msg); +// +// } } /** @@ -363,6 +474,26 @@ class Client return $this->client->index($params); } + + /** + * 添加子文档 + * @param $id + * @param $doc + * @param string $type_name + */ + public function addChildDoc($id, $parent_id, $doc, string $type_name = '_doc') + { + $params = [ + 'index' => $this->index, + 'type' => $type_name, + 'id' => $id, + 'routing' => $parent_id,//与父文档在同一个分区 + 'body' => $doc + ]; + + return $this->client->index($params); + } + public function getIndex() { return $this->index; @@ -389,7 +520,14 @@ class Client { return [ 'number_of_shards' => 1, - 'number_of_replicas' => 0 + 'number_of_replicas' => 0, + 'analysis' => [ + 'analyzer' => [ + 'default' => [ + 'type' => 'ik_smart' + ] + ] + ], ]; } @@ -470,11 +608,8 @@ class Client } /** - * @return bool - * @throws Exception - */ public function createIndexNew($mapping) @@ -486,9 +621,9 @@ class Client $check = $this->indices()->exists($params); -// if ($check) { -// throw new Exception('index: ' . $this->index . ' already exists'); -// } + if ($check->getStatusCode() == 200) { + throw new Exception('index: ' . $this->index . ' already exists'); + } $params = [ 'index' => $this->index, @@ -503,6 +638,8 @@ class Client ] ]; +// dd($params); + $result = $this->indices()->create($params); return $result['acknowledged'] === true; @@ -585,9 +722,7 @@ class Client */ public function doBulkDocument($type = 1,$data = []) - { - try { $params = ['body' => []]; @@ -659,11 +794,9 @@ class Client /** * 更新索引 * @return array @todo - */ public function updateIndex($mappings) - { $putParams = [ @@ -685,35 +818,22 @@ class Client } /** - * 方便调试, 直接返回拼接的query - * @return $this - */ - public function setDebug() - { - $this->debug = true; - return $this; - } private function indices() - { - return $this->client->indices(); - } public function analyze($text = '') - { - $params = [ 'index' => $this->index, @@ -729,13 +849,10 @@ class Client ]; return $this->indices()->analyze($params); - } public function update($id = 0, $updateParams = []) - { - $params = [ 'index' => $this->index, diff --git a/app/common/service/GoodsCateEs.php b/app/common/service/GoodsCateEs.php new file mode 100644 index 00000000..c16eb579 --- /dev/null +++ b/app/common/service/GoodsCateEs.php @@ -0,0 +1,533 @@ +esService = Client::setEs($this->index_name); + } + + + /** + * 查询分类列表 + * @param $params + */ + public function list(array $params = [],$page = 1, $limit = 10) + { + $between = $ins = []; + $like = ['goods_name' => $params['goods_name'] ?? '']; + $equal = ['status' => $params['status']]; + if (isset($params['fliter_condition']) && $params['fliter_condition']) { + $fliter_condition = json_decode($params['fliter_condition'], true); + foreach ($fliter_condition as $key => $value) + { + $between[] = [ + 'category_id' => $value['category'], + 'profit' => $value['profit'], + 'profit_rate' => $value['profit_rate'] + ]; + } + unset($params['fliter_condition']); + + } + + if (!empty($params['channels'])) { + $ins = ['channels' => $params['channels']]; + unset($params['channels']); + } + + return $this->esService + ->select($this->field) + ->like($like) + ->hasChild($between) + ->in($ins) + ->equal($equal) + ->from($page) + ->size($limit) + ->order(['goods_id' => 'desc']) +// ->setDebug() + ->query(); + } + + public function count($params = [],$page = 1, $limit = 10) + { + $between = $ins = []; + $like = ['goods_name' => $params['goods_name'] ?? '']; + $equal = ['status' => $params['status']]; + if (isset($params['fliter_condition']) && $params['fliter_condition']) { + $fliter_condition = json_decode($params['fliter_condition'], true); + foreach ($fliter_condition as $key => $value) + { + $between[] = [ + 'category_id' => $value['category'], + 'profit' => $value['profit'], + 'profit_rate' => $value['profit_rate'] + ]; + } + unset($params['fliter_condition']); + + } + + if (!empty($params['channels'])) { + $ins = ['channels' => $params['channels']]; + unset($params['channels']); + } + return $this->esService +// ->setDebug() + ->like($like) + ->hasChild($between) + ->in($ins) + ->equal($equal) + ->from($page) + ->size($limit) + ->query(true); + } + + + /** + * 更新商品 + */ + public function updateData($goods_id, $data) + { + return $this->esService->update($goods_id, $data); + } + + /** + * 查询商品详情 + */ + public function detail($goods_id) + { + return $this->esService->getDoc($goods_id); + } + + /** + * 创建商品 + */ + public function createData($goods_id, $list) + { + $list['goods_category_field'] = [ + 'name' => 'goods' + ]; + return $this->esService->addDoc('goods_'.$goods_id, $list)->asArray(); + } + + /** + * 创建商品分类 + */ + public function createCateData($id, $value) + { + + $parent_id = 'goods_'.$value['goods_id']; + $doc = [ + 'id' => $value['id'], + 'category_id' => $value['category_id'], + 'cate_store_id' => $value['store_id'], +// 'cate_create_time' => strtotime($value['create_time']), + 'cate_create_time' => $value['create_time'], + 'goods_category_field' => [ + 'name' => 'category', + 'parent' => $parent_id + ], + + ]; + return $this->esService->addDoc('category_'.$id, $doc)->asArray(); + } + + + /** + * 批量创建数据 + * @return + */ + public function batchCreateData() + { + for ($page = 1; $page<=224; $page++) + { + $this->addData($page); +// sleep(1); + } + } + + public function addData($page) + { + $goods_cate_list = GoodsCategoryRel::where('category_id', '>', 0) + ->where('id', '>', 1628858) + ->where('goods_id', '>', 0) +// ->order('goods_id desc') + ->page($page) + ->limit(5000) + ->select() + ->toArray(); +// dd($goods_cate_list); +// + $i = 0; + if (!empty($goods_cate_list)){ + foreach ($goods_cate_list as $value) + { + $parent_id = 'goods_'.$value['goods_id']; + $doc = [ + 'id' => $value['id'], + 'category_id' => $value['category_id'], + 'cate_store_id' => $value['store_id'], +// 'cate_create_time' => strtotime($value['create_time']), + 'cate_create_time' => $value['create_time'], + 'goods_category_field' => [ + 'name' => 'category', + 'parent' => $parent_id + ], + + ]; +// dd($doc); + $res = $this->esService->addChildDoc('category_'.$value['id'], $parent_id, $doc)->asArray(); + if($res['result'] == 'created') + { + $i++; + } + } + } + + echo('同步成功'.$i.'条数据').PHP_EOL; + } + + /** + * 批量创建商品 + * @return + */ + public function batchCreateGoodsData() + { + for ($page = 1; $page<=173; $page++) + { + $this->addGoodsData($page); +// sleep(1); + } + } + + public function addGoodsData($page) + { + $goods_list = Goods::where('goods_id', '>', 0) +// ->order('goods_id desc') + ->page($page) + ->limit(2000) + ->select() + ->toArray(); +// dd($goods_list); +// + $i = 0; + foreach ($goods_list as $value) + { +// $value['create_time'] = $value['create_time']; +// $value['update_time'] = $value['update_time']; + $value['delivery_type'] = implode(',', $value['delivery_type']); + $value['goods_category_field'] = [ + 'name' => 'goods' + ]; + $res = $this->esService->addDoc('goods_'.$value['goods_id'], $value)->asArray(); + if($res['result'] == 'created') + { + $i++; + } + } + + echo('同步成功'.$i.'条数据').PHP_EOL; + } + + /** + * 删除商品 + */ + public function delete($goods_id) + { + return $this->esService->deleteDoc($goods_id); + } + + /** + * 删除索引 + */ + public function deleteIndex() + { + return $this->esService->deleteIndexNew(); + } + + /** + * 创建商品分类关联索引 + */ + public function createGoodsCateIndex() + { + + $mapping = [ + 'properties' => [ + 'goods_id' => [ + 'type' => 'keyword' + ], + 'goods_type' => [ + 'type' => 'keyword' + ], + 'goods_name' => [ + 'type' => 'text', + "analyzer" => "ik_smart" + ], + 'goods_no' => [ + 'type' => 'keyword', + ], + 'video_id' => [ + 'type' => 'integer' + ], + 'brand_id' => [ + 'type' => 'integer' + ], + 'video_cover_id' => [ + 'type' => 'integer' + ], + 'selling_point' => [ + 'type' => 'text', + "analyzer" => "ik_smart" + ], + 'spec_type' => [ + 'type' => 'integer' + ], + 'cost_price_min' => [ + 'type' => 'float' + ], + 'goods_price_min' => [ + 'type' => 'float' + ], + 'goods_price_max' => [ + 'type' => 'float' + ], + 'line_price_min' => [ + 'type' => 'float' + ], + 'line_price_max' => [ + 'type' => 'float' + ], + 'stock_total' => [ + 'type' => 'integer' + ], + 'deduct_stock_type' => [ + 'type' => 'integer' + ], + 'is_restrict' => [ + 'type' => 'integer' + ], + 'restrict_total' => [ + 'type' => 'integer' + ], + 'restrict_single' => [ + 'type' => 'integer' + ], + 'content' => [ + 'type' => 'text', + ], + 'sales_initial' => [ + 'type' => 'integer' + ], + 'delivery_id' => [ + 'type' => 'integer' + ], + 'is_points_gift' => [ + 'type' => 'integer' + ], + 'is_points_discount' => [ + 'type' => 'integer' + ], + 'is_alone_points_discount' => [ + 'type' => 'integer' + ], + 'points_discount_config' => [ + 'type' => 'text' + ], + 'is_enable_grade' => [ + 'type' => 'integer' + ], + 'is_alone_grade' => [ + 'type' => 'integer' + ], + 'alone_grade_equity' => [ + 'type' => 'text' + ], + 'is_ind_dealer' => [ + 'type' => 'integer' + ], + 'dealer_money_type' => [ + 'type' => 'integer' + ], + 'first_money' => [ + 'type' => 'float' + ], + 'second_money' => [ + 'type' => 'float' + ], + 'third_money' => [ + 'type' => 'float' + ], + 'is_ind_delivery_type' => [ + 'type' => 'integer' + ], + 'delivery_type' => [ + 'type' => 'keyword' + ], + 'status' => [ + 'type' => 'integer' + ], + 'sort' => [ + 'type' => 'integer' + ], + 'store_id' => [ + 'type' => 'keyword' + ], + 'merchant_id' => [ + 'type' => 'keyword' + ], + 'create_time' => [ + 'type' => 'date', + 'format' => 'yyyy-MM-dd HH:mm:ss' + ], + 'update_time' => [ + 'type' => 'date', + 'format' => 'yyyy-MM-dd HH:mm:ss' + ], + 'is_brand' => [ + 'type' => 'integer' + ], + 'is_new' => [ + 'type' => 'integer' + ], + 'paihang' => [ + 'type' => 'integer' + ], + 'remaizhishu' => [ + 'type' => 'integer' + ], + 'spu_id' => [ + 'type' => 'integer' + ], + 'channel' => [ + 'type' => 'keyword' + ], + 'unicode' => [ + 'type' => 'keyword' + ], + 'is_in_store' => [ + 'type' => 'integer' + ], + 'profit' => [ + 'type' => 'float' + ], + 'profit_rate' => [ + 'type' => 'float' + ], + 'cmmdty_model'=> [ + 'type' => 'keyword' + ], + 'remark' => [ + 'type' => 'text' + ], + 'sale_areas' => [ + 'type' => 'text' + ], + 'sale_areas_id' => [ + 'type' => 'keyword' + ], + 'data_type' => [ + 'type' => 'integer' + ], + 'is_pool' => [ + 'type' => 'integer' + ], + 'is_self' => [ + 'type' => 'integer' + ], + 'link' => [ + 'type' => 'keyword' + ], + 'origin_goods_id' => [ + 'type' => 'integer' + ], + 'link_other' => [ + 'type' => 'text' + ], + 'goods_no_other' => [ + 'type' => 'keyword' + ], + 'region' => [ + 'type' => 'text' + ], + 'region_text' => [ + 'type' => 'text' + ], + 'specific_value' => [ + 'type' => 'keyword' + ], + 'cate_status' => [ + 'type' => 'integer' + ], + 'is_check' => [ + 'type' => 'integer' + ], + 'goods_source' => [ + 'type' => 'keyword' + ], + 'delivery_time' => [ + 'type' => 'integer' + ], + 'distribute_price' => [ + 'type' => 'float' + ], + 'shop_price' => [ + 'type' => 'float' + ], + 'is_has_banner' => [ + 'type' => 'integer' + ], + 'is_has_detail' => [ + 'type' => 'integer' + ], + 'is_jingpin' => [ + 'type' => 'integer' + ], + 'sale_time' => [ + 'type' => 'integer' + ], + 'markup_rate' => [ + 'type' => 'integer' + ], + 'id' => [ + 'type' => 'integer' + ], + 'category_id' => [ + 'type' => 'integer' + ], + 'cate_store_id' => [ + 'type' => 'integer' + ], + 'cate_create_time' => [ + 'type' => 'integer' + ], + 'goods_category_field' => [ + 'type' => 'join', + 'relations' => [ + 'goods' => 'category' + ] + ] + ] + ]; + + return $this->esService->createIndexNew($mapping); + + } + + + + +} \ No newline at end of file