问一下搜索表full_search_product_en的更新方法。
程序里面好像没要发现添加或者编辑产品,更新索引表的机制。
产品的编辑是在后台,后台编辑保存,对应的方法为: https://github.com/fecshop/yii2_fecshop/blob/master/app/appadmin/modules/Catalog/block/productinfo/Manageredit.php
public function save() { $this->initParamType(); /* * if attribute is date or date time , db storage format is int ,by frontend pass param is int , * you must convert string datetime to time , use strtotime function. */ // var_dump() if (Yii::$app->request->post('operate') == 'copy') { if (isset($this->_param['_id'])) { unset($this->_param['_id']); //echo 111; //var_dump($this->_param); //exit; } } $this->_service->save($this->_param, 'catalog/product/index'); $errors = Yii::$service->helper->errors->get(); if (!$errors) { echo json_encode([ 'statusCode'=>'200', 'message'=>'save success', ]); exit; } else { echo json_encode([ 'statusCode'=>'300', 'message'=>$errors, ]); exit; } }
在上面的函数中存在下面这行代码,这个代码的作用是保存产品。 $this->_service->save($this->_param, 'catalog/product/index');
$this->_service->save($this->_param, 'catalog/product/index');
上面这行代码执行的是:https://github.com/fecshop/yii2_fecshop/blob/master/services/product/ProductMongodb.php
/** * @property $one|array , 产品数据数组 * @property $originUrlKey|string , 产品的原来的url key ,也就是在前端,分类的自定义url。 * 保存产品(插入和更新),以及保存产品的自定义url * 如果提交的数据中定义了自定义url,则按照自定义url保存到urlkey中,如果没有自定义urlkey,则会使用name进行生成。 */ public function save($one, $originUrlKey = 'catalog/product/index') { if (!$this->initSave($one)) { return; } $one['min_sales_qty'] = (int)$one['min_sales_qty']; $currentDateTime = \fec\helpers\CDate::getCurrentDateTime(); $primaryVal = isset($one[$this->getPrimaryKey()]) ? $one[$this->getPrimaryKey()] : ''; if ($primaryVal) { $model = $this->_productModel->findOne($primaryVal); if (!$model) { Yii::$service->helper->errors->add('Product '.$this->getPrimaryKey().' is not exist'); return; } //验证sku 是否重复 $product_one = $this->_productModel->find()->asArray()->where([ '<>', $this->getPrimaryKey(), (new \MongoDB\BSON\ObjectId($primaryVal)), ])->andWhere([ 'sku' => $one['sku'], ])->one(); if ($product_one['sku']) { Yii::$service->helper->errors->add('Product Sku 已经存在,请使用其他的sku'); return; } } else { $model = new $this->_productModelName(); $model->created_at = time(); $model->created_user_id = \fec\helpers\CUser::getCurrentUserId(); $primaryVal = new \MongoDB\BSON\ObjectId(); $model->{$this->getPrimaryKey()} = $primaryVal; //验证sku 是否重复 $product_one = $this->_productModel->find()->asArray()->where([ 'sku' => $one['sku'], ])->one(); if ($product_one['sku']) { Yii::$service->helper->errors->add('Product Sku 已经存在,请使用其他的sku'); return; } } $model->updated_at = time(); /* * 计算出来产品的最终价格。 */ $one['final_price'] = Yii::$service->product->price->getFinalPrice($one['price'], $one['special_price'], $one['special_from'], $one['special_to']); $one['score'] = (int) $one['score']; unset($one['_id']); /** * 保存产品 */ $saveStatus = Yii::$service->helper->ar->save($model, $one); /* * 自定义url部分 */ if ($originUrlKey) { $originUrl = $originUrlKey.'?'.$this->getPrimaryKey() .'='. $primaryVal; $originUrlKey = isset($one['url_key']) ? $one['url_key'] : ''; $defaultLangTitle = Yii::$service->fecshoplang->getDefaultLangAttrVal($one['name'], 'name'); $urlKey = Yii::$service->url->saveRewriteUrlKeyByStr($defaultLangTitle, $originUrl, $originUrlKey); $model->url_key = $urlKey; $model->save(); } $product_id = $model->{$this->getPrimaryKey()}; /** * 更新产品库存。 */ Yii::$service->product->stock->saveProductStock($product_id,$one); /** * 更新产品信息到搜索表。 */ Yii::$service->search->syncProductInfo([$product_id]); return true; }
在上面函数的最后,就是更新产品信息到搜索表,也就是下面的代码:
Yii::$service->search->syncProductInfo([$product_id]);
这个代码的作用是将save的product的信息更新到搜索部分
然后,打开文件,https://github.com/fecshop/yii2_fecshop/blob/master/services/search/MongoSearch.php
找到函数
/** * @property $product_ids | Array ,里面的子项是MongoId类型。 * 将产品表的数据同步到各个语言对应的搜索表中。 */ protected function actionSyncProductInfo($product_ids, $numPerPage) { $sModel = $this->_searchModel; if (is_array($product_ids) && !empty($product_ids)) { $productPrimaryKey = Yii::$service->product->getPrimaryKey(); $searchModel = new $this->_searchModelName(); $filter['select'] = $searchModel->attributes(); $filter['asArray'] = true; $filter['where'][] = ['in', $productPrimaryKey, $product_ids]; $filter['numPerPage'] = $numPerPage; $filter['pageNum'] = 1; $coll = Yii::$service->product->coll($filter); if (is_array($coll['coll']) && !empty($coll['coll'])) { foreach ($coll['coll'] as $one) { //$langCodes = Yii::$service->fecshoplang->allLangCode; //if(!empty($langCodes) && is_array($langCodes)){ // foreach($langCodes as $langCodeInfo){ $one_name = $one['name']; $one_description = $one['description']; $one_short_description = $one['short_description']; if (!empty($this->searchLang) && is_array($this->searchLang)) { foreach ($this->searchLang as $langCode => $mongoSearchLangName) { $sModel::$_lang = $langCode; $searchModel = $this->_searchModel->findOne(['_id' => $one['_id']]); if (!$searchModel['_id']) { $searchModel = new $this->_searchModelName(); }else{ unset($one['_id']); } $one['name'] = Yii::$service->fecshoplang->getLangAttrVal($one_name, 'name', $langCode); $one['description'] = Yii::$service->fecshoplang->getLangAttrVal($one_description, 'description', $langCode); $one['short_description'] = Yii::$service->fecshoplang->getLangAttrVal($one_short_description, 'short_description', $langCode); $one['sync_updated_at'] = time(); Yii::$service->helper->ar->save($searchModel, $one); if ($errors = Yii::$service->helper->errors->get()) { // 报错。 echo $errors; //return false; } } } } } } //echo "MongoSearch sync done ... \n"; return true; }
可以看到将各个语言的部分都更新了
@Terry #2楼 谢谢,很详细,我只是后台更新产品,前台没要看到效果,代码没要细看。 再次感谢详细的解答。
@dosenje #3楼 加断点或者log输出检测一下问题所在。
@dosenje #3楼 你的这个搜索没有更新的问题解决了?
@Terry #5楼 解决了,程序没有问题,运行了重建索引那个命令。就可以了。
@dosenje #6楼 然后,后面,在后台新建的产品,会自动加入到搜索表里面吧?
@Terry #7楼 会的,新建的和修改的都会。