/** * @param $str 文字 * @param $first 是否只取各個漢字的拼音首字 默認全拼 * @param $spac 分隔符 */ function pinyin($str, $first = false, $spac = '') { $py = new py_class(); if ($first) { $py->all = false; } return $py->str2py($str, $spac); }
public function SearchAppKeyword($keyword, &$cacheHit, $soft_type = self::APPSTORE) { $RET = array(); if ($soft_type == self::APPSTORE) { $cache = Factory::Redis(ClusterRedis::CLUSTER_APP); list($keywordCacheKey, $expire) = $cache->GetStrategy()->GetAppSearchKeywordKey($keyword); } elseif ($soft_type == self::GAME_CENTER) { $cache = Factory::Redis(ClusterRedis::CLUSTER_GAME_APP); list($keywordCacheKey, $expire) = $cache->GetStrategy()->GetAppSearchKeywordKey($keyword); } /** get Cache */ if (AppLogic::IsUseCache()) { if ($keywordCacheKey && ($res = $cache->get($keywordCacheKey)) && ($searchRs = Util::JsonDec($res, TRUE))) { $cacheHit = TRUE; } } if (!isset($searchRs)) { // 判断是否是包名 if (!$this->isPackage($keyword)) { // 繁体转简体 $keyword = ChineseConvert::t2s($keyword); $categoryId = CategoryLogic::GetCategoryMap($keyword); // 分词 $ws = new WordSegment(); $segWord = $ws->AddDict(WordSegment::DEFAULT_DICT)->AddDict(WordSegment::USER_DICT, WordSegment::DICT_TYPE_TEXT)->SetIgnorePunc(TRUE)->Slice($keyword)->GetResult(array($ws, 'cbMergeWithPipe')); // 如果分词结果不是字符串 if (!is_string($segWord)) { return false; } // 整词列表 if ($this->WholeWords($keyword)) { $segWord .= '|(' . $keyword . ')'; } // 中文做单字拼接 /* $len = mb_strlen($keyword, 'UTF-8'); for($i=0; $i<$len; $i++) { $w = mb_substr($keyword, $i, 1, 'UTF-8'); $wlen = strlen($w); if($wlen >= 3) { $segWord .= '|('. $w .')'; } } */ // 分词结果转拼音 $pyWord = py_class::str2py($segWord); Log::Single()->Info("Search Word", array('key' => $keyword, 'seg' => $segWord, 'py' => $pyWord)); $pyWord = $this->filterKeyword($pyWord); } else { $segWord = ''; $pyWord = ''; $package = $keyword; Log::Single()->Info("Search package", array('key' => $keyword)); } $this->search->setFilterRange('status', 1, 1); if ($soft_type == self::GAME_CENTER) { $this->search->setFilterRange('soft_type', 1, 1); } $this->search->setMatchMode(SPH_MATCH_EXTENDED2); $this->search->setSortMode(SPH_SORT_EXTENDED, '@relevance DESC, download DESC, scores DESC, last_update_time DESC'); $this->search->setFieldWeights($this->GetSearchAppWeightMap()); $this->search->setMaxQueryTime(3000); $this->search->setRankingMode(SPH_RANK_SPH04); //$this->search->setRankingMode(SPH_RANK_EXPR, 'sum((exact_hit*5+(min_hit_pos==1)*2+lcs)*user_weight)*1000+bm25'); $this->search->setLimits(0, 100, self::DEFAULT_SEARCH_TOTAL, self::DEFAULT_SEARCH_TOTAL); $this->search->setArrayResult(TRUE); $indexs = implode(',', $this->GetSearchAppIndex()); if (!$this->isPackage($keyword)) { $filterWordArr = $this->GetSearchAppFilterWord(); $filterDeveloper = 0; foreach ($filterWordArr as $word) { if (strpos($keyword, $word) !== FALSE) { $filterDeveloper = 1; break; } } // addQuerys $this->search->addQuery("@name {$segWord}", $indexs); $this->search->addQuery("@cname {$segWord}", $indexs); if ($pyWord) { $pyWordArr = explode('|', $pyWord); foreach ($pyWordArr as $pyName) { $this->search->addQuery("@py_name {$pyName}", $indexs); } $this->search->addQuery("@py_cname {$pyWord}", $indexs); } $this->search->addQuery("@tag {$segWord}", $indexs); if (!$filterDeveloper) { $this->search->addQuery("@developer {$segWord}", $indexs); } $cateQuery = $categoryId ? "@(category) (^{$categoryId})|({$categoryId}\$)|(,{$categoryId},)" : ""; if ($cateQuery) { $this->search->addQuery($cateQuery, $indexs); } } else { $this->search->addQuery("@package {$package}", $indexs); } $res = $this->search->runQueries(); if (is_array($res)) { $error = ''; $warning = ''; $searchRs = array(); foreach ($res as $k => $v) { if (isset($v['error']) && $v['error']) { $error .= $k . ':' . $v['error'] . ' & '; } if (isset($v['warning']) && $v['warning']) { $warning .= $k . ':' . $v['warning'] . ' & '; } // matches if (isset($v['matches']) && $v['matches']) { foreach ($v['matches'] as $data) { if (!array_key_exists($data['id'], $searchRs)) { $searchRs[$data['id']] = $data['weight']; } else { $searchRs[$data['id']] += $data['weight']; } } } } arsort($searchRs); /** 写Cache */ if ($searchRs && $keywordCacheKey) { $cache->multi(Redis::MULTI); $cache->set($keywordCacheKey, Util::JsonEnc($searchRs)); $expire && $cache->expire($keywordCacheKey, $expire); $cache->exec(); } // log error if (!empty($error)) { Log::Single()->Error("Sphinx error", array('error' => $error, 'keyword' => $keyword, 'segWord' => $segWord, 'py' => $pyWord)); } // log warning if (!empty($warning)) { Log::Single()->Warn("Sphinx warning", array('warning' => $warning)); } } } if (isset($searchRs) && $searchRs) { $pageSize = 20; $offset = 0; $sliceSearchRs = array_slice($searchRs, $offset, $pageSize, TRUE); $count = count($sliceSearchRs); $idx = 0; foreach ($sliceSearchRs as $appId => $weight) { $RET[$appId] = $weight; $idx++; if ($idx >= $pageSize) { break; } } } return $RET; }