Search.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. /*
  3. * FecShop file.
  4. *
  5. * @link http://www.fecshop.com/
  6. * @copyright Copyright (c) 2016 FecShop Software LLC
  7. * @license http://www.fecshop.com/license/
  8. */
  9. namespace fecshop\services;
  10. use fecshop\services\search\MongoSearch;
  11. use Yii;
  12. /**
  13. * Product Search.
  14. * @author Terry Zhao <2358269014@qq.com>
  15. * @since 1.0
  16. */
  17. class Search extends Service
  18. {
  19. /**
  20. * 在搜索页面侧栏的搜索过滤属性字段.
  21. */
  22. public $filterAttr;
  23. /**
  24. * 在搜索页面, spu相同的sku,是否只显示其中score高的sku,其他的sku隐藏
  25. * 如果设置为true,那么在搜索结果页面,spu相同,sku不同的产品,只会显示score最高的那个产品
  26. * 如果设置为false,那么在搜索结果页面,所有的sku都显示。
  27. * 这里做设置的好处,譬如服装,一个spu的不同颜色尺码可能几十个产品,都显示出来会占用很多的位置,对于这种产品您可以选择设置true
  28. * 这个针对的京东模式的产品
  29. */
  30. public $productSpuShowOnlyOneSku = true;
  31. // 当前有效的子services
  32. protected $_childServiceNames;
  33. public function init()
  34. {
  35. //if($this->currentSearchEngine == 'MongoSearch'){
  36. // $this->_searchEngine = new MongoSearch;
  37. //}else if($this->currentSearchEngine == 'XunSearch'){
  38. // $this->_searchEngine = new XunSearch;
  39. //}
  40. parent::init();
  41. }
  42. /**
  43. * init search engine index.
  44. */
  45. protected function actionInitFullSearchIndex()
  46. {
  47. //exit;
  48. $searchEngineList = $this->getAllChildServiceName();
  49. if (is_array($searchEngineList) && !empty($searchEngineList)) {
  50. foreach ($searchEngineList as $sE) {
  51. $service = $this->{$sE};
  52. $service->initFullSearchIndex();
  53. }
  54. }
  55. }
  56. public function getAllChildServiceName()
  57. {
  58. if (!$this->_childServiceNames) {
  59. $childServiceName = parent::getAllChildServiceName();
  60. // 从数据库配置中得到值, 设置成当前service存储,是Mysqldb 还是 Mongodb
  61. $searchConfig = Yii::$app->store->get('search_engine');
  62. $enableSearch = [];
  63. if (is_array($searchConfig)) {
  64. foreach ($searchConfig as $engine => $status) {
  65. if ($status == Yii::$app->store->enable) {
  66. $enableSearch[] = $engine;
  67. }
  68. }
  69. }
  70. // 当前的子search service,查看哪些是enable的
  71. if (is_array($childServiceName) && !empty($childServiceName)) {
  72. foreach ($childServiceName as $sE) {
  73. if (in_array($sE, $enableSearch)) {
  74. $this->_childServiceNames[] = $sE;
  75. }
  76. }
  77. }
  78. }
  79. return $this->_childServiceNames;
  80. }
  81. /**
  82. * @param $product_ids | Array 产品id数组
  83. * 批量处理,将所有产品批量同步到搜索工具的库里面。
  84. */
  85. protected function actionSyncProductInfo($product_ids, $numPerPage = 20)
  86. {
  87. $searchEngineList = $this->getAllChildServiceName();
  88. if (is_array($searchEngineList) && !empty($searchEngineList)) {
  89. foreach ($searchEngineList as $sE) {
  90. $service = $this->{$sE};
  91. $service->syncProductInfo($product_ids, $numPerPage);
  92. }
  93. }
  94. }
  95. /**
  96. * @param $nowTimeStamp | int
  97. * 批量更新过程中,被更新的产品都会更新字段sync_updated_at
  98. * 删除xunSearch引擎中sync_updated_at小于$nowTimeStamp的字段.
  99. */
  100. protected function actionDeleteNotActiveProduct($nowTimeStamp)
  101. {
  102. $searchEngineList = $this->getAllChildServiceName();
  103. if (is_array($searchEngineList) && !empty($searchEngineList)) {
  104. foreach ($searchEngineList as $sE) {
  105. $service = $this->{$sE};
  106. $service->deleteNotActiveProduct($nowTimeStamp);
  107. }
  108. }
  109. }
  110. /**
  111. * @param $select | Array
  112. * @param $where | Array
  113. * @param $pageNum | Int
  114. * @param $numPerPage | Array
  115. * @param $product_search_max_count | Int , 搜索结果最大产品数。
  116. * 对于上面的参数和以前的$filter类似,大致和下面的类似
  117. * [
  118. * 'category_id' => 1,
  119. * 'pageNum' => 2,
  120. * 'numPerPage' => 50,
  121. * 'orderBy' => 'name',
  122. * 'where' => [
  123. * ['>','price',11],
  124. * ['<','price',22],
  125. * ],
  126. * 'select' => ['xx','yy'],
  127. * 'group' => '$spu',
  128. * ]
  129. * 得到搜索的产品列表.
  130. */
  131. protected function actionGetSearchProductColl($select, $where, $pageNum, $numPerPage, $product_search_max_count, $filterAttr = [])
  132. {
  133. // 当前有效的搜索引擎
  134. $searchEngineList = $this->getAllChildServiceName();
  135. // 语言对应
  136. $currentSearchEngine = $this->getCurrentSearchEngine();
  137. if (in_array($currentSearchEngine, $searchEngineList)) {
  138. $service = $this->{$currentSearchEngine};
  139. return $service->getSearchProductColl($select, $where, $pageNum, $numPerPage, $product_search_max_count, $filterAttr);
  140. }
  141. }
  142. /**
  143. * 得到搜索的sku列表侧栏的过滤.
  144. * @param $filter_attr | Array
  145. * @param $where | Array , like
  146. * [
  147. * ['>','price',11],
  148. * ['<','price',22],
  149. * ],
  150. */
  151. protected function actionGetFrontSearchFilter($filter_attr, $where)
  152. {
  153. // 当前有效的搜索引擎
  154. $searchEngineList = $this->getAllChildServiceName();
  155. // 语言对应
  156. $currentSearchEngine = $this->getCurrentSearchEngine();
  157. if (in_array($currentSearchEngine, $searchEngineList)) {
  158. $service = $this->{$currentSearchEngine};
  159. return $service->getFrontSearchFilter($filter_attr, $where);
  160. }
  161. }
  162. protected $_currentSearchEngine;
  163. // 得到当前语言对应的搜索引擎
  164. public function getCurrentSearchEngine()
  165. {
  166. if (!$this->_currentSearchEngine) {
  167. $currentLangCode = Yii::$service->store->currentLangCode;
  168. if (!$currentLangCode) {
  169. return null;
  170. }
  171. $langArr = Yii::$app->store->get('mutil_lang');
  172. $langCodeAndEngine = [];
  173. foreach ($langArr as $one) {
  174. $langCodeAndEngine[$one['lang_code']] = $one['search_engine'];
  175. }
  176. if (!isset($langCodeAndEngine[$currentLangCode])) {
  177. return null;
  178. }
  179. $this->_currentSearchEngine = $langCodeAndEngine[$currentLangCode];
  180. }
  181. return $this->_currentSearchEngine;
  182. }
  183. /**
  184. * 通过product_id删除搜索数据.
  185. * @param $product_id | \mongoId
  186. */
  187. protected function actionRemoveByProductId($product_id)
  188. {
  189. $searchEngineList = $this->getAllChildServiceName();
  190. if (is_array($searchEngineList) && !empty($searchEngineList)) {
  191. foreach ($searchEngineList as $sE) {
  192. $service = $this->{$sE};
  193. $service->removeByProductId($product_id);
  194. }
  195. }
  196. }
  197. }