提交 45fd12ae 编写于 作者: R root

fecshop product search (use mongodb full text search)

上级 bb8f4992
......@@ -19,11 +19,12 @@ return [
'category_filter_attr' =>[
'color','size',
],
'category_filter_category' => true,
'category_filter_price' => true,
'category_query' =>[
# 放到第一个的就是默认值,譬如下面的30
'numPerPage' => [30,60,90], # 产品显示个数的列举
'numPerPage' => [4,30,60,90], # 产品显示个数的列举
# 放到第一个的就是默认值,譬如下面的hot
'sort' => [ # 所有排序方式
# 下面的譬如hot new low-to-high 只能用 字母,数组,-,_ 这4种字符。
......
......@@ -10,7 +10,63 @@ return [
'catalogsearch' => [
'class' => '\fecshop\app\appfront\modules\Catalogsearch\Module',
'params'=> [
'categorysearch_filter_attr' =>[
'color','size',
],
# 搜索页面的title 格式 ,%s 将会被替换成搜索词
'search_page_title_format' => 'Search Text: %s ',
# 搜索页面的 meta keywords格式 ,%s 将会被替换成搜索词
'search_page_meta_keywords_format' => 'Search Text: %s ',
# 搜索页面的 meta description格式 ,%s 将会被替换成搜索词
'search_page_meta_description_format' => 'Search Text: %s ',
# 搜索的最大个数
'product_search_max_count' => 1000,
# 搜索页面是否开启面包屑导航
'search_breadcrumbs' => true,
//'search_filter_category' => true,
'search_query' =>[
# 放到第一个的就是默认值,譬如下面的30
'numPerPage' => [4,30,60,90], # 产品显示个数的列举
# 放到第一个的就是默认值,譬如下面的hot
'sort' => [ # 所有排序方式
# 下面的譬如hot new low-to-high 只能用 字母,数组,-,_ 这4种字符。
'hot' => [
'label' => 'Hot', # 显示的字符
'db_columns'=> 'score', # 对应数据库的字段
'direction' => 'desc', # 排序方式
],
'new' => [
'label' => 'New',
'db_columns'=> 'created_at',
'direction' => 'desc',
],
'low-to-high' => [
'label' => '$ Low to High',
'db_columns'=> 'price',
'direction' => 'asc',
],
'high-to-low' => [
'label' => '$ High to Low',
'db_columns'=> 'price',
'direction' => 'desc',
],
],
# 价格区间设置,如果不想在搜索页面价格过滤,可以清空这个。
'price_range' => [
'0-10',
'10-20',
'20-30',
'30-50',
'50-100',
'100-150',
'150-300',
'300-500',
'500-1000',
'1000-',
],
],
],
],
];
......
......@@ -10,6 +10,7 @@ namespace fecshop\app\appfront\modules\Catalog\block\category;
use Yii;
use fec\helpers\CModule;
use fec\helpers\CRequest;
use yii\base\InvalidValueException;
/**
* @author Terry Zhao <2358269014@qq.com>
* @since 1.0
......@@ -30,9 +31,12 @@ class Index {
protected $_filterPriceAttr = 'price';
protected $_productCount;
protected $_filter_attr;
protected $_numPerPageVal;
public function getLastData(){
# 每页显示的产品个数,进行安全验证,如果个数不在预先设置的值内,则会报错。
# 这样是为了防止恶意攻击,也就是发送很多不同的页面个数的链接,绕开缓存。
$this->getNumPerPage();
//echo Yii::$service->page->translate->__('fecshop,{username}', ['username' => 'terry']);
$this->initCategory();
......@@ -309,18 +313,30 @@ class Index {
}
protected function getNumPerPage(){
$numPerPage = Yii::$app->request->get($this->_numPerPage);
if(!$numPerPage){
if(!$this->_numPerPageVal){
$numPerPage = Yii::$app->request->get($this->_numPerPage);
$category_query_config = Yii::$app->controller->module->params['category_query'];
if(isset($category_query_config['numPerPage'])){
if(is_array($category_query_config['numPerPage'])){
return $category_query_config['numPerPage'][0];
if(!$numPerPage){
if(isset($category_query_config['numPerPage'])){
if(is_array($category_query_config['numPerPage'])){
$this->_numPerPageVal = $category_query_config['numPerPage'][0];
}
}
}else if(!$this->_numPerPageVal){
if(isset($category_query_config['numPerPage']) && is_array($category_query_config['numPerPage'])){
$numPerPageArr = $category_query_config['numPerPage'];
if(in_array((int)$numPerPage,$numPerPageArr)){
$this->_numPerPageVal = $numPerPage;
}else{
throw new InvalidValueException('Incorrect numPerPage value:'.$numPerPage);
}
}
}
}
return $numPerPage;
return $this->_numPerPageVal;
}
protected function getPageNum(){
$numPerPage = Yii::$app->request->get($this->_page);
return $numPerPage ? (int)$numPerPage : 1;
......
......@@ -10,13 +10,414 @@ namespace fecshop\app\appfront\modules\Catalogsearch\block\index;
use Yii;
use fec\helpers\CModule;
use fec\helpers\CRequest;
use yii\base\InvalidValueException;
/**
* @author Terry Zhao <2358269014@qq.com>
* @since 1.0
*/
class Index {
protected $_searchText;
protected $_title;
protected $_primaryVal;
protected $_defautOrder;
protected $_defautOrderDirection = SORT_DESC;
protected $_where;
protected $_numPerPage = 'numPerPage';
protected $_direction = 'dir';
protected $_sort = 'sort';
protected $_page = 'p';
protected $_filterPrice = 'price';
protected $_filterPriceAttr = 'price';
protected $_productCount;
protected $_filter_attr;
protected $_numPerPageVal;
public function getLastData(){
return [];
$this->getNumPerPage();
//echo Yii::$service->page->translate->__('fecshop,{username}', ['username' => 'terry']);
$this->initSearch();
# change current layout File.
//Yii::$service->page->theme->layoutFile = 'home.php';
$productCollInfo = $this->getSearchProductColl();
$products = $productCollInfo['coll'];
$this->_productCount= $productCollInfo['count'];
//echo $this->_productCount;
return [
'title' => $this->_title,
'name' => Yii::$service->store->getStoreAttrVal($this->_category['name'],'name'),
'image' => $this->_category['image'] ? Yii::$service->category->image->getUrl($this->_category['image']) : '',
'description' => Yii::$service->store->getStoreAttrVal($this->_category['description'],'description'),
'products' => $products,
'query_item' => $this->getQueryItem(),
'product_page' => $this->getProductPage(),
'refine_by_info'=> $this->getRefineByInfo(),
'filter_info' => $this->getFilterInfo(),
'filter_price' => $this->getFilterPrice(),
//'filter_category'=> $this->getFilterCategoryHtml(),
//'content' => Yii::$service->store->getStoreAttrVal($this->_category['content'],'content'),
//'created_at' => $this->_category['created_at'],
];
}
/**
* 得到子分类,如果子分类不存在,则返回同级分类。
*/
protected function getFilterCategory(){
$category_id = $this->_primaryVal;
$parent_id = $this->_category['parent_id'];
$filter_category = Yii::$service->category->getFilterCategory($category_id,$parent_id);
return $filter_category;
}
protected function getFilterCategoryHtml($filter_category=''){
$str = '';
if(!$filter_category){
$filter_category = $this->getFilterCategory();
}
if(is_array($filter_category) && !empty($filter_category)){
$str .= '<ul>';
foreach($filter_category as $cate){
$name = Yii::$service->store->getStoreAttrVal($cate['name'],'name');
$url = Yii::$service->url->getUrl($cate['url_key']);
$current = '';
if(isset($cate['current']) && $cate['current']){
$current = 'class="current"';
}
$str .= '<li '.$current.'><a href="'.$url.'">'.$name.'</a>';
if(isset($cate['child']) && is_array($cate['child'] ) && !empty($cate['child'])){
$str .= $this->getFilterCategoryHtml($cate['child']);
}
$str .= '</li>';
}
$str .= '</ul>';
}
//exit;
return $str;
}
protected function getProductPage(){
$productNumPerPage = $this->getNumPerPage();
$productCount = $this->_productCount;
$pageNum = $this->getPageNum();
//echo $productCount;
$config = [
'class' => 'fecshop\app\appfront\widgets\Page',
'view' => 'widgets/page.php',
'pageNum' => $pageNum,
'numPerPage' => $productNumPerPage,
'countTotal' => $productCount,
'page' => $this->_page,
];
return Yii::$service->page->widget->renderContent('category_product_page',$config);
}
protected function getQueryItem(){
$category_query = Yii::$app->controller->module->params['search_query'];
$numPerPage = $category_query['numPerPage'];
$sort = $category_query['sort'];
$frontNumPerPage = [];
if(is_array($numPerPage) && !empty($numPerPage)){
$attrUrlStr = $this->_numPerPage;
foreach($numPerPage as $np){
$urlInfo = Yii::$service->url->category->getFilterChooseAttrUrl($attrUrlStr,$np,$this->_page);
//var_dump($url);
//exit;
$frontNumPerPage[] = [
'value' => $np,
'url' => $urlInfo['url'],
'selected' => $urlInfo['selected'],
];
}
}
$data = [
'frontNumPerPage' => $frontNumPerPage,
// 'frontSort' => $frontSort,
];
//var_dump($data);
return $data;
}
protected function getFilterAttr(){
if(!$this->_filter_attr){
$this->_filter_attr = Yii::$app->controller->module->params['categorysearch_filter_attr'];
}
return $this->_filter_attr;
}
protected function getRefineByInfo(){
$get_arr = Yii::$app->request->get();
//var_dump($get_arr);
if(is_array($get_arr) && !empty($get_arr)){
$refineInfo = [];
$filter_attrs = $this->getFilterAttr();
$filter_attrs[] = 'price';
//var_dump($filter_attrs);
$currentUrl = Yii::$service->url->getCurrentUrl();
foreach($get_arr as $k=>$v){
$attr = Yii::$service->url->category->urlStrConvertAttrVal($k);
//echo $attr;
if(in_array($attr,$filter_attrs)){
if($attr == 'price'){
$refine_attr_str = $this->getFormatFilterPrice($v);
//$refine_attr_str = Yii::$service->url->category->urlStrConvertAttrVal($v);
}else{
$refine_attr_str = Yii::$service->url->category->urlStrConvertAttrVal($v);
}
$removeUrlParamStr = $k.'='.$v;
$refine_attr_url = Yii::$service->url->removeUrlParamVal($currentUrl,$removeUrlParamStr);
$refineInfo[] = [
'name' => $refine_attr_str,
'url' => $refine_attr_url,
];
}
}
}
if(!empty($refineInfo)){
$arr[] = [
'name' => 'clear all',
'url' => Yii::$service->url->getCurrentUrlNoParam(),
];
$refineInfo = array_merge($arr,$refineInfo);
}
return $refineInfo;
}
protected function getFilterInfo(){
$filter_info = [];
$filter_attrs = $this->getFilterAttr();
//var_dump($this->_where);exit;
foreach($filter_attrs as $attr){
$filter_info[$attr] = Yii::$service->product->getFrontCategoryFilter($attr,$this->_where);
}
return $filter_info;
}
protected function getFilterPrice(){
$filter = [];
$priceInfo = Yii::$app->controller->module->params['search_query'];
//var_dump($priceInfo);
if(isset($priceInfo['price_range']) && !empty($priceInfo['price_range']) && is_array($priceInfo['price_range'])){
foreach($priceInfo['price_range'] as $price_item){
$info = Yii::$service->url->category->getFilterChooseAttrUrl($this->_filterPrice,$price_item,$this->_page);
$info['val'] = $this->getFormatFilterPrice($price_item);
$filter[$this->_filterPrice][] = $info;
}
}
return $filter;
}
protected function getFormatFilterPrice($price_item){
list($f_price,$l_price) = explode('-',$price_item);
$str = '';
if($f_price == '0' || $f_price){
$f_price = Yii::$service->product->price->formatPrice($f_price);
$str .= $f_price['symbol'].$f_price['value'].'---';
}
if($l_price){
$l_price = Yii::$service->product->price->formatPrice($l_price);
$str .= $l_price['symbol'].$l_price['value'];
}
return $str;
}
protected function getFilterArr($str){
$arr = [];
if($str){
$str = str_replace(',',',',$str);
$str_arr = explode(",",$str);
foreach($str_arr as $a){
$a = trim($a);
if($a){
$arr[] = trim($a);
}
}
}
return $arr;
}
protected function getOrderBy(){
$primaryKey = Yii::$service->category->getPrimaryKey();
$sort = Yii::$app->request->get($this->_sort);
$direction = Yii::$app->request->get($this->_direction);
$category_query_config = Yii::$app->controller->module->params['category_query'];
if(isset($category_query_config['sort'])){
$sortConfig = $category_query_config['sort'];
if(is_array($sortConfig)){
//return $category_query_config['numPerPage'][0];
if($sort && isset($sortConfig[$sort])){
$orderInfo = $sortConfig[$sort];
}else{
foreach($sortConfig as $k => $v){
$orderInfo = $v;
if(!$direction){
$direction = $v['direction'];
}
break;
}
}
$db_columns = $orderInfo['db_columns'];
if($direction == 'desc'){
$direction = -1;
}else{
$direction = 1;
}
//var_dump([$db_columns => $direction]);
return [$db_columns => $direction];
}
}
}
protected function getNumPerPage(){
if(!$this->_numPerPageVal){
$numPerPage = Yii::$app->request->get($this->_numPerPage);
$category_query_config = Yii::$app->controller->module->params['search_query'];
if(!$numPerPage){
if(isset($category_query_config['numPerPage'])){
if(is_array($category_query_config['numPerPage'])){
$this->_numPerPageVal = $category_query_config['numPerPage'][0];
}
}
}else if(!$this->_numPerPageVal){
if(isset($category_query_config['numPerPage']) && is_array($category_query_config['numPerPage'])){
$numPerPageArr = $category_query_config['numPerPage'];
if(in_array((int)$numPerPage,$numPerPageArr)){
$this->_numPerPageVal = $numPerPage;
}else{
throw new InvalidValueException('Incorrect numPerPage value:'.$numPerPage);
}
}
}
}
return $this->_numPerPageVal;
}
protected function getPageNum(){
$numPerPage = Yii::$app->request->get($this->_page);
return $numPerPage ? (int)$numPerPage : 1;
}
protected function getSearchProductColl(){
$select = [
'sku','spu','name','image',
'price','special_price',
'special_from','special_to',
'url_key','score',
];
$category_query = Yii::$app->controller->module->params['search_query'];
if(is_array($category_query['sort'])){
foreach($category_query['sort'] as $sort_item){
$select[] = $sort_item['db_columns'];
}
}
$filter = [
'pageNum' => $this->getPageNum(),
'numPerPage' => $this->getNumPerPage(),
'where' => $this->_where,
'product_search_max_count' => Yii::$app->controller->module->params['product_search_max_count'],
'select' => $select,
];
//var_dump($filter);exit;
$collection = Yii::$service->product->fullTearchText($filter);
$collection['coll'] = Yii::$service->category->product->convertToCategoryInfo($collection['coll']);
return $collection;
}
protected function initWhere(){
$filterAttr = $this->getFilterAttr();
foreach($filterAttr as $attr){
$attrUrlStr = Yii::$service->url->category->attrValConvertUrlStr($attr);
$val = Yii::$app->request->get($attrUrlStr);
if($val){
$val = Yii::$service->url->category->urlStrConvertAttrVal($val);
$where[$attr] = $val;
}
}
$filter_price = Yii::$app->request->get($this->_filterPrice);
list($f_price,$l_price) = explode('-',$filter_price);
if($f_price == '0' || $f_price){
$where[$this->_filterPriceAttr]['$gte'] = (float)$f_price;
}
if($l_price){
$where[$this->_filterPriceAttr]['$lte'] = (float)$l_price;
}
//$where['category'] = $this->_primaryVal;
//var_dump($where);exit;
$where['$text'] = ['$search' => $this->_searchText];
$where['status'] = 1;
$where['is_in_stock'] = 1;
$this->_where = $where;
return $where;
}
protected function initSearch(){
//$primaryKey = Yii::$service->category->getPrimaryKey();
//$primaryVal = Yii::$app->request->get($primaryKey);
//$this->_primaryVal = $primaryVal;
//$category = Yii::$service->category->getByPrimaryKey($primaryVal);
//$this->_category = $category ;
$searchText = Yii::$app->request->get('q');
$this->_searchText = $searchText;
$search_page_title_format = Yii::$app->controller->module->params['search_page_title_format'];
$search_page_meta_keywords_format = Yii::$app->controller->module->params['search_page_meta_keywords_format'];
$search_page_meta_description_format= Yii::$app->controller->module->params['search_page_meta_description_format'];
$this->breadcrumbs();
if($search_page_title_format){
$title = str_replace('%s',$searchText,$search_page_title_format);
}else{
$title = $searchText;
}
if($search_page_meta_keywords_format){
$meta_keywords = str_replace('%s',$searchText,$search_page_meta_keywords_format);
}else{
$meta_keywords = $searchText;
}
if($search_page_meta_description_format){
$meta_description = str_replace('%s',$searchText,$search_page_meta_description_format);
}else{
$meta_description = $searchText;
}
Yii::$app->view->registerMetaTag([
'name' => 'keywords',
'content' => $meta_keywords,
]);
Yii::$app->view->registerMetaTag([
'name' => 'description',
'content' => $meta_description,
]);
$this->_title = $title;
Yii::$app->view->title = $this->_title;
$this->_where = $this->initWhere();
}
# 面包屑导航
protected function breadcrumbs(){
if(Yii::$app->controller->module->params['search_breadcrumbs']){
Yii::$service->page->breadcrumbs->addItems(['name' => $this->_searchText]);
}else{
Yii::$service->page->breadcrumbs->active = false;
}
}
}
\ No newline at end of file
......@@ -31,7 +31,7 @@ $(document).ready(function(){
if($(this).hasClass("checked")){
$(this).removeClass("checked");
}else{
$(".filter_attr_info a.checked").removeClass("checked");
$(this).parent().find("a.checked").removeClass("checked");
$(this).addClass("checked");
}
});
......
<?php if(isset($parentThis['current_category']) && isset($parentThis['filter_category'])){ ?>
<div class="category_left_filter_category">
<div class="filter_attr_title">
<?php echo $parentThis['current_category']; ?>
......@@ -6,3 +7,4 @@
<?php echo $parentThis['filter_category']; ?>
</div>
</div>
<?php } ?>
\ No newline at end of file
......@@ -4,9 +4,10 @@
?>
<div class="toolbar">
<div class="tb_le">
<b>Sort By:</b>
<?php $frontSort = $query_item['frontSort']; ?>
<?php if(is_array($frontSort) && !empty($frontSort)){ ?>
<b>Sort By:</b>
<select class="product_sort">
<?php foreach($frontSort as $np){ ?>
<?php $selected = $np['selected'] ? 'selected="selected"' : ''; ?>
......
......@@ -8,12 +8,115 @@
*/
?>
<div class="main container two-columns-left">
<?php // echo count($products); ?>
<?php $count = 4; $end = $count-1; ?>
<div class="col-main">
<?= Yii::$service->page->widget->render('breadcrumbs',$this); ?>
<div class="menu_category">
<div class="panelBar">
<?php if(is_array($products) && !empty($products)){ ?>
<?php
$parentThis = [
'query_item' => $query_item,
'product_page'=>$product_page,
];
$config = [
'view' => 'catalogsearch/index/index/toolbar.php',
];
$toolbar = Yii::$service->page->widget->renderContent('category_toolbar',$config,$parentThis);
echo $toolbar;
?>
<?php } ?>
</div>
<div class="category_product">
<?php if(is_array($products) && !empty($products)){ ?>
<?php $i = 0; foreach($products as $product){ ?>
<?php if($i%$count == 0){ ?>
<ul>
<?php } ?>
<li>
<div class="c_img">
<a href="<?= $product['url'] ?>">
<img src="<?= Yii::$service->product->image->getResize($product['image'],[230,230],false) ?>" />
</a>
</div>
<div class="c_name">
<a href="<?= $product['url'] ?>">
<?= $product['name'] ?>
</a>
</div>
<?php
$config = [
'class' => 'fecshop\app\appfront\modules\Catalog\block\category\Price',
'view' => 'catalog/category/price.php',
'price' => $product['price'],
'special_price' => $product['special_price'],
];
echo Yii::$service->page->widget->renderContent('category_product_price',$config);
?>
</li>
<?php if($i%$count == $end){ ?>
</ul>
<?php } ?>
<?php $i++; ?>
<?php } ?>
<?php if($i%$count != $end){ ?>
</ul>
<?php } ?>
<?php } ?>
</div>
<div class="clear"></div>
<div class="panelBar">
<?php if(is_array($products) && !empty($products)){ ?>
<?php echo $toolbar; ?>
<?php } ?>
</div>
</div>
</div>
<div class="col-left ">
<?php
# Refind By
$parentThis = [
'refine_by_info' => $refine_by_info,
];
$config = [
'view' => 'catalog/category/index/filter/refineby.php',
];
echo Yii::$service->page->widget->renderContent('category_product_filter_refine_by',$config,$parentThis);
?>
<?php
# Category Left Filter subCategory
$parentThis = [
'filter_category' => $filter_category,
'current_category'=> $name,
];
$config = [
'view' => 'catalog/category/index/filter/subcategory.php',
];
echo Yii::$service->page->widget->renderContent('category_product_filter_sub_category',$config,$parentThis);
?>
<?php
# Category Left Filter Product Attributes
$parentThis = [
'filters' => $filter_info,
];
$config = [
'view' => 'catalog/category/index/filter/attr.php',
];
echo Yii::$service->page->widget->renderContent('category_product_filter_attr',$config,$parentThis);
?>
<?php
# Category Left Filter Product Price
$parentThis = [
'filter_price' => $filter_price,
];
$config = [
'view' => 'catalog/category/index/filter/price.php',
];
echo Yii::$service->page->widget->renderContent('category_product_filter_price',$config,$parentThis);
?>
</div>
<div class="clear"></div>
</div>
\ No newline at end of file
<?php
$query_item = $parentThis['query_item'];
$product_page = $parentThis['product_page'];
?>
<div class="toolbar">
<div class="tb_le">
<?php $frontNumPerPage = $query_item['frontNumPerPage']; ?>
<?php if(is_array($frontNumPerPage) && !empty($frontNumPerPage)){ ?>
<b>Show Per Page:</b>
<select class="product_num_per_page">
<?php foreach($frontNumPerPage as $np){ ?>
<?php $selected = $np['selected'] ? 'selected="selected"' : ''; ?>
<?php $url = $np['url']; ?>
<option <?= $selected; ?> url="<?= $url; ?>" value="<?= $np['value']; ?>"><?= $np['value']; ?></option>
<?php } ?>
</select>
<?php } ?>
</div>
<?= $product_page ?>
<div class="clear"></div>
</div>
......@@ -125,6 +125,10 @@ class Product extends Service
protected function actionGetFrontCategoryFilter($filter_attr,$where){
return $this->_product->getFrontCategoryFilter($filter_attr,$where);
}
protected function actionFullTearchText($filter){
return $this->_product->fullTearchText($filter);
}
}
......@@ -65,9 +65,16 @@ class Product extends Service
$coll = Yii::$service->product->getFrontCategoryProducts($filter);
$collection = $coll['coll'];
$count = $coll['count'];
$arr = $this->convertToCategoryInfo($collection);
return [
'coll' => $arr,
'count'=> $count,
];
}
protected function actionConvertToCategoryInfo($collection){
$arr = [];
//var_dump($collection);
//var_dump($count);
$defaultImg = Yii::$service->product->image->defautImg();
if(is_array($collection) && !empty($collection)){
foreach($collection as $one){
......@@ -91,10 +98,7 @@ class Product extends Service
];
}
}
return [
'coll' => $arr,
'count'=> $count,
];
return $arr;
}
......
......@@ -313,6 +313,121 @@ class ProductMongodb implements ProductInterface
$filter_data = Product::getCollection()->aggregate($pipelines);
return $filter_data;
}
/**
* 全文搜索
* $filter Example:
* $filter = [
* 'pageNum' => $this->getPageNum(),
* 'numPerPage' => $this->getNumPerPage(),
* 'where' => $this->_where,
* 'product_search_max_count' => Yii::$app->controller->module->params['product_search_max_count'],
* 'select' => $select,
* ];
*/
public function fullTearchText($filter){
$where = $filter['where'];
$product_search_max_count = $filter['product_search_max_count'] ? $filter['product_search_max_count'] : 1000;
$mongodb = Yii::$app->mongodb;
$select = $filter['select'];
$pageNum = $filter['pageNum'];
$numPerPage = $filter['numPerPage'];
$orderBy = $filter['orderBy'];
#
/**
* 说明:1.'search_score'=>['$meta'=>"textScore" ,这个是text搜索为了排序,
* 详细参看:https://docs.mongodb.com/manual/core/text-search-operators/
* 2. sort排序:search_score是全文搜索匹配后的得分,score是product表的一个字段,这个字段可以通过销售量或者其他作为参考设置。
*/
$search_data = $mongodb->getCollection('product_flat')
->find($where,['search_score'=>['$meta'=>"textScore" ],'id' => 1 ,'spu'=> 1,'score' => 1,])
->sort( ['search_score'=> [ '$meta'=> 'textScore' ],'score' => -1] )
->limit($product_search_max_count)
;
/**
* 通过下面的数组,在spu相同,而且name description相同的的多个sku产品,只显示一个,因为上面已经排序,
* 因此,显示的是score最高的一个
*/
$data = [];
foreach($search_data as $one){
if(!isset($data[$one['spu']])){
$data[$one['spu']] = $one;
}
}
$count = count($data);
$offset = ($pageNum -1)*$numPerPage;
$limit = $numPerPage;
$productIds = [];
foreach($data as $d){
$productIds[] = $d['_id'];
}
$productIds = array_slice($productIds, $offset, $limit);
if(!empty($productIds)){
$query = Product::find()->asArray()
->select($select)
->where(['_id'=> ["?in"=>$productIds]])
;
$data = $query->all();
/**
* 下面的代码的作用:将结果按照上面in查询的顺序进行数组的排序,使结果和上面的搜索结果排序一致(_id)。
*/
$s_data = [];
foreach($data as $one){
$_id = $one['_id']->{'$id'};
$s_data[$_id] = $one;
}
$return_data = [];
foreach($productIds as $product_id){
$return_data[] = $s_data[$product_id->{'$id'}];
}
return [
'coll' => $return_data ,
'count'=> $count,
];
}
}
/*
$project = [];
$group['_id'] = $filter['group'];
foreach($select as $column){
$project[$column] = 1;
if($column != '_id'){
$group[$column] = ['$first' => '$'.$column];
}else{
$group['mongo_id'] = ['$first' => '$'.$column];
}
}
$pipelines = [
[
'$match' => $where,
],
[
'$project' => $project
],
[
'$group' => $group,
],
];
//var_dump($pipelines);
//exit;
$data = Product::getCollection()->aggregate($pipelines);
*/
//var_dump($where);exit;
//var_dump($productIds );
//$data = Product::getCollection()
// ->fullTextSearch($searchText,[],['_id'],['limit'=>$product_search_max_count])
// ;
//exit;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册