소스 검색

feat:空搜索调整

fuwencai 2 년 전
부모
커밋
10de9a35f6
2개의 변경된 파일181개의 추가작업 그리고 69개의 파일을 삭제
  1. 27 21
      jyBXBuyer/rpc/internal/logic/buyerlistlogic.go
  2. 154 48
      jyBXBuyer/rpc/model/buyerListBYEs.go

+ 27 - 21
jyBXBuyer/rpc/internal/logic/buyerlistlogic.go

@@ -29,7 +29,9 @@ func NewBuyerListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BuyerLi
 // 采购单位搜索
 func (l *BuyerListLogic) BuyerList(in *bxbuyer.BuyerListReq) (*bxbuyer.BuyerListResp, error) {
 	logx.Info("----:", model.CheckEmpty(in))
-	resp := &bxbuyer.BuyerListResp{}
+	resp := &bxbuyer.BuyerListResp{
+		Data: &bxbuyer.BuyerData{},
+	}
 	// 采购单位搜索过来的 最多查100条
 	if in.PageSize*in.PageNum > IC.C.BuyerSearchLimit {
 		in.PageNum = IC.C.BuyerSearchLimit / in.PageSize
@@ -43,43 +45,48 @@ func (l *BuyerListLogic) BuyerList(in *bxbuyer.BuyerListReq) (*bxbuyer.BuyerList
 	query, CountQuery := "", ""
 	buyerNames := []string{}
 	if model.CheckEmpty(in) {
-		//获取缓存数据
 		var isBool = true
-		bs, err := redis.GetBytes("other", fmt.Sprintf(model.P_redis_key, in.PageNum, in.PageSize))
+		list := []*bxbuyer.BuyerList{} //100条数据
+		bs, err := redis.GetBytes("other", fmt.Sprintf(model.P_redis_key))
 		if err == nil && bs != nil && len(*bs) > 0 {
 			isBool = false
-			if err := json.Unmarshal(*bs, &resp.Data); err != nil {
+			if err := json.Unmarshal(*bs, &list); err != nil {
 				isBool = true
 				logx.Info("获取redis缓存,序列化异常")
 			} else {
-				if len(resp.Data.List) > 0 {
+				if len(list) > 0 {
+					// 根据页码返回数据
+					start := in.PageSize * (in.PageNum - 1)
+					end := in.PageSize*in.PageNum + 1
+					count := len(list)
+					resp.Data.Count = int64(count)
+					if end > int64(len(list)-1) {
+						end = int64(len(list) - 1)
+					}
+					resp.Data.List = list[start:end]
 					for i := 0; i < len(resp.Data.List); i++ {
 						buyerNames = append(buyerNames, resp.Data.List[i].Buyer)
 					}
+				} else {
+					isBool = true
 				}
-
 			}
 		}
 		if isBool {
-			query, CountQuery = model.BuyerListRedisCacheQuery(in.PageNum, in.PageSize)
-			buyerNames, resp = model.GetBuyerList(query, CountQuery, true)
-			if len(resp.Data.List) > 0 {
-				//model.SupplyBuyerListData(buyerNames, resp)
-				b, err := json.Marshal(resp.Data)
-				if err == nil {
-					redis.PutBytes("other", fmt.Sprintf(model.P_redis_key, in.PageNum, in.PageSize), &b, model.P_redis_time)
-				} else {
-					logx.Info("缓存数据 序列化异常")
-				}
-			}
+			/*
+				空搜索
+				1. 聚合出来200条采购单位数据  项目数量 采购单位规模 可以直接一块出来
+				2. 查采购单位库确认100条数据有效
+				3. 存一周缓存
+			*/
+			query = model.BuyerListRedisCacheQuery(in.PageNum, in.PageSize)
+			buyerNames, resp = model.BuyerListRedisCache(query, in)
+
 		}
 	} else {
 		query, CountQuery = model.BuyerListQuery(in)
 		logx.Info("query:", query)
 		buyerNames, resp = model.GetBuyerList(query, CountQuery, false) // 查询数据
-		//if len(resp.Data.List) > 0 {
-		//	model.SupplyBuyerListData(buyerNames, resp)
-		//}
 	}
 	if len(resp.Data.List) > 0 && (in.UserId != "" || in.EntUserId != "") {
 		model.SupplyFollowInfo(in, buyerNames, resp)
@@ -87,6 +94,5 @@ func (l *BuyerListLogic) BuyerList(in *bxbuyer.BuyerListReq) (*bxbuyer.BuyerList
 	if resp.Data.Count > IC.C.BuyerSearchLimit {
 		resp.Data.Count = IC.C.BuyerSearchLimit
 	}
-
 	return resp, nil
 }

+ 154 - 48
jyBXBuyer/rpc/model/buyerListBYEs.go

@@ -28,10 +28,16 @@ type BScope struct {
 	AdditionalWords []string `json:"additionalWords"`
 	ExcludedWords   []string `json:"excludedWords"`
 }
+type supplyDataStruct struct {
+	ProjectCount   int64
+	BidCount       int64
+	BidAmountCount float32
+	ContactCount   int64
+}
 
 // 获取采购单位查询query
 func BuyerListQuery(in *bxbuyer.BuyerListReq) (qstr string, CountQstr string) {
-	query := `{%s "query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer_name": ""}}],"should":[%s],"minimum_should_match": %d}}}`
+	query := `{%s "query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer_name": ""}}],"should":[%s],"minimum_should_match": %d}},"sort":[{"updatetime":"desc"}]}`
 	//21.1.20  为和画像保持一致  数据组要求 budget 改成 bidamount
 	query_bool_should := `{"bool":{"should":[%s],"minimum_should_match": 1}}`
 
@@ -100,16 +106,18 @@ func getTimeRange() (st, et time.Time) {
 }
 
 const (
-	P_INDEX                  = "projectset"
-	P_TYPE                   = "projectset"
-	P_redis_time             = 15 * 24 * 60 * 60      //redis存15天
-	P_redis_key              = "buyerListCache_%d_%d" // 按页存缓存
-	BuyerIndex               = "buyer"                // 采购单位index
-	BuyerType                = "buyer"
-	biddingIndex             = "bidding"
-	biddingType              = "bidding"
-	BuyerSupplyInfoRedisKey  = "BuyerSupplyInfo_%s" // 采购单位补充信息缓存
-	BuyerSupplyInfoRedisTime = 5 * 60               // 采购单位补充信息缓存时间
+	P_INDEX                   = "projectset"
+	P_TYPE                    = "projectset"
+	P_redis_time              = 7 * 24 * 60 * 60       //redis存7天
+	P_redis_key               = "buyerListCache_%d_%d" // 存缓存 100条数据
+	BuyerIndex                = "buyer"                // 采购单位index
+	BuyerType                 = "buyer"
+	biddingIndex              = "bidding"
+	biddingType               = "bidding"
+	BuyerSupplyInfoRedisKey   = "BuyerSupplyInfo_%s"  // 采购单位补充信息缓存
+	BuyerSupplyInfoRedisTime  = 5 * 60                // 采购单位补充信息缓存时间
+	BuyerProjectInfoRedisKey  = "BuyerProjectInfo_%s" // 采购单位补充项目信息缓存Key  (项目数量采购规模)
+	BuyerProjectInfoRedisTime = 24 * 60 * 60          // 采购单位补充项目信息缓存时间
 )
 
 // GetBuyerList 查询采购单位列表
@@ -146,6 +154,106 @@ func GetBuyerList(qstr string, CountQuery string, isCache bool) (buyerNames []st
 	return
 }
 
+// BuyerListRedisCache 空搜索 1.查询项目数量最多的前200个 2.然后 再查buyer里确认数据有效 100个 3.项目数量和采购规模单独存缓存 1天
+func BuyerListRedisCache(query string, in *bxbuyer.BuyerListReq) (buyerNames []string, resp *bxbuyer.BuyerListResp) {
+	//获取缓存数据
+	resp = &bxbuyer.BuyerListResp{
+		Data: &bxbuyer.BuyerData{
+			List: []*bxbuyer.BuyerList{},
+		},
+	}
+	t1 := time.Now()
+	logx.Info("耗时1:", time.Since(t1))
+	aggs := GetAggs(P_INDEX, P_TYPE, query)
+	logx.Info("查询语句:", query)
+	logx.Info("BuyerListRedisCache:", time.Since(t1))
+	type BuyerAggStruct struct {
+		Buckets []struct {
+			Key            string `json:"key,omitempty"`
+			Doc_count      int64  `json:"doc_count,omitempty"`
+			BidAmountCount struct {
+				Value float32 `json:"value,omitempty"`
+			} `json:"bidAmountCount"`
+		} `json:"buckets"`
+	}
+	var buyerBuckets = BuyerAggStruct{}
+	saveBuyerList := []*bxbuyer.BuyerList{} //100条数据 最后存起来
+	// 处理成map 用于后面格式化数据
+	if aggs == nil || aggs["buyerBuckets"] == nil {
+		return
+	}
+	bs, err := aggs["buyerBuckets"].MarshalJSON()
+	if err != nil {
+		resp.ErrCode = -1
+		resp.ErrMsg = "获取数据异常"
+		return
+	}
+	if len(bs) == 0 {
+		resp.ErrMsg = "暂无数据"
+		return
+	}
+	err = json.Unmarshal(bs, &buyerBuckets)
+	if err != nil || len(buyerBuckets.Buckets) == 0 {
+		resp.ErrMsg = "暂无数据"
+		return
+	}
+	for i := 0; i < len(buyerBuckets.Buckets); i++ {
+		if len(saveBuyerList) == 100 {
+			break
+		}
+		// 查buyer  确认数据存在 补充 buyerclass 省份 城市信息
+		rs := GetBuyer(buyerBuckets.Buckets[i].Key)
+		if rs != nil && len(*rs) > 0 { // 存在 则追加
+			tmpBuyerInfo := (*rs)[0]
+			buyerInfo := &bxbuyer.BuyerList{
+				Buyer:      buyerBuckets.Buckets[i].Key,
+				Province:   MC.ObjToString(tmpBuyerInfo["province"]),
+				City:       MC.ObjToString(tmpBuyerInfo["city"]),
+				BuyerClass: MC.ObjToString(tmpBuyerInfo["buyerclass"]),
+			}
+			saveBuyerList = append(saveBuyerList, buyerInfo)
+			buyerNames = append(buyerNames, buyerInfo.Buyer)
+			// 项目数量和采购规模存缓存 1天
+			projectCacheData := supplyDataStruct{
+				ProjectCount:   buyerBuckets.Buckets[i].Doc_count,
+				BidAmountCount: buyerBuckets.Buckets[i].BidAmountCount.Value,
+			}
+			go func(buyer string, data supplyDataStruct) {
+				b, err := json.Marshal(data)
+				if err == nil {
+					redis.PutBytes("other", fmt.Sprintf(BuyerProjectInfoRedisKey, buyer), &b, BuyerProjectInfoRedisTime+GetRand(60))
+				}
+			}(buyerBuckets.Buckets[i].Key, projectCacheData)
+
+		}
+	}
+	if len(saveBuyerList) > 0 {
+		//  100 列表存redis 7天
+		go func(data []*bxbuyer.BuyerList) {
+			b, err := json.Marshal(data)
+			if err == nil {
+				redis.PutBytes("other", fmt.Sprintf(P_redis_key), &b, P_redis_time)
+			}
+		}(saveBuyerList)
+	}
+	// 根据页码返回数据
+	start := in.PageSize * (in.PageNum - 1)
+	end := in.PageSize*in.PageNum + 1
+	resp.Data.Count = int64(len(saveBuyerList))
+	if end > int64(len(saveBuyerList)-1) {
+		end = int64(len(saveBuyerList) - 1)
+	}
+	resp.Data.List = saveBuyerList[start:end]
+	return
+}
+
+// GetBuyer 查采购单位表 确认采购单位存在
+func GetBuyer(buyerName string) *[]map[string]interface{} {
+	q := `{"size":1,"_source":["buyerclass","province","city"],"query":{"bool":{"must":[{"term":{"buyer_name":"%s"}}]}}}`
+	rs := elastic.Get(BuyerIndex, BuyerType, fmt.Sprintf(q, buyerName))
+	return rs
+}
+
 // SupplyFollowInfo 补充是否关注信息
 func SupplyFollowInfo(in *bxbuyer.BuyerListReq, buyerNames []string, resp *bxbuyer.BuyerListResp) *bxbuyer.BuyerListResp {
 
@@ -181,12 +289,6 @@ func SupplyFollowInfo(in *bxbuyer.BuyerListReq, buyerNames []string, resp *bxbuy
 
 // SupplyBuyerListData 补充字段   招标动态数量 项目数量 历史联系人数量 采购单位规模
 func SupplyBuyerListData(buyerNames []string, resp *bxbuyer.BuyerListResp) *bxbuyer.BuyerListResp {
-	type supplyDataStruct struct {
-		ProjectCount   int64
-		BidCount       int64
-		BidAmountCount float32
-		ContactCount   int64
-	}
 	//buyerNames 是否存在缓存 数据
 	//如果没有 放到一个新的 []string
 	needSearchBuyer := []string{}
@@ -310,37 +412,56 @@ func SupplyBuyerListData(buyerNames []string, resp *bxbuyer.BuyerListResp) *bxbu
 	return resp
 }
 
+// 获取项目数量 采购单位规模
+func getBuyerProjectCache(buyer string) (rs *supplyDataStruct) {
+	bs, err := redis.GetBytes("other", fmt.Sprintf(BuyerProjectInfoRedisKey, buyer))
+	if err == nil && bs != nil && len(*bs) > 0 {
+		if err := json.Unmarshal(*bs, &rs); err != nil {
+			logx.Info("获取redis缓存,序列化异常")
+		} else {
+			return rs
+		}
+	}
+	return
+}
+
 // BuyerSupplyInfo 补充字段
 func BuyerSupplyInfo(buyerNames []string) (resp *bxbuyer.BuyerSupplyResp) {
 	resp = &bxbuyer.BuyerSupplyResp{}
 	start := time.Now()
 	// buyerNames
-	type supplyDataStruct struct {
-		ProjectCount   int64
-		BidCount       int64
-		BidAmountCount float32
-		ContactCount   int64
-	}
 	//buyerNames 是否存在缓存 数据
 	//如果没有 放到一个新的 []string
 	needSearchBuyer := []string{}
 	cacheMap := map[string]supplyDataStruct{}
+	buyerMap := map[string]supplyDataStruct{}
 	for i := 0; i < len(buyerNames); i++ {
 		bs, err := redis.GetBytes("other", fmt.Sprintf(BuyerSupplyInfoRedisKey, buyerNames[i]))
 		if err == nil && bs != nil && len(*bs) > 0 {
 			tmp := supplyDataStruct{}
 			if err := json.Unmarshal(*bs, &tmp); err == nil {
-				cacheMap[buyerNames[i]] = tmp // 拿到缓存的数据
+				cacheMap[buyerNames[i]] = tmp // 拿到缓存的数据  采购规模 项目数量 联系人数量 招标动态数量
 			} else {
-				needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查
-			}
+				// 查缓存
+				cacheProject := getBuyerProjectCache(buyerNames[i])
+				if cacheProject != nil {
+					buyerMap[buyerNames[i]] = *cacheProject
+				} else {
+					needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查采购规模和项目数量
+				}
 
+			}
 		} else {
-			needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查
+			// 查缓存
+			cacheProject := getBuyerProjectCache(buyerNames[i])
+			if cacheProject != nil {
+				buyerMap[buyerNames[i]] = *cacheProject
+			} else {
+				needSearchBuyer = append(needSearchBuyer, buyerNames[i]) // 没有缓存的数据 后边再查采购规模和项目数量
+			}
 		}
 
 	}
-	buyerMap := map[string]supplyDataStruct{}
 	if len(needSearchBuyer) > 0 {
 		t1 := time.Now()
 		query := SupplyDataQuery(buyerNames) // 项目数量、采购规模
@@ -399,7 +520,7 @@ func BuyerSupplyInfo(buyerNames []string) (resp *bxbuyer.BuyerSupplyResp) {
 			resp.Data[i].ContactCount = cacheData.ContactCount
 			continue
 		}
-		// 缓存里没有的再查数据补充
+		// 缓存里没有的再查数据补充
 		// 补充字段
 		if supplyData, ok := buyerMap[buyer]; ok {
 			resp.Data[i].BidAmountCount = supplyData.BidAmountCount
@@ -616,23 +737,8 @@ func CheckEmpty(in *bxbuyer.BuyerListReq) bool {
 //缓存数据查询
 
 // 获取采购单位查询query
-func BuyerListRedisCacheQuery(pageNum, pageSize int64) (qstr string, cstr string) {
-	query := `{"from":%d,"size":%d,"query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer_name": ""}}],"should":[],"minimum_should_match": %d}}}`
-	queryCount := `{"query":{"bool":{"must":[%s],"must_not": [{"term": {"buyer": ""}}],"should":[],"minimum_should_match": %d}}}`
-	//21.1.20  为和画像保持一致  数据组要求 budget 改成 bidamount
-	musts := []string{}
-	boolsNum := 0
-	entcustomerClass := `{"terms":{"buyer_name":[`
-	for k, v := range IC.C.DefaultBuyerNames {
-		if k > 0 {
-			entcustomerClass += `,`
-		}
-		entcustomerClass += `"` + v + `"`
-	}
-	entcustomerClass += `]}}`
-	musts = append(musts, entcustomerClass)
-	qstr = fmt.Sprintf(query, (pageNum-1)*pageSize, pageSize, strings.Join(musts, ","), boolsNum)
-	cstr = fmt.Sprintf(queryCount, strings.Join(musts, ","), boolsNum)
-	logx.Info("qstr:", qstr)
-	return
+func BuyerListRedisCacheQuery(pageNum, pageSize int64) (qstr string) {
+	qstr = `{"size":0,"query":{"bool":{"must_not":[{"term":{"buyer":""}}]}},"aggs":{"buyerBuckets":{"terms":{"field":"buyer","order":[{"_count":"desc"}],"size":200},"aggs":{"bidAmountCount":{"sum":{"field":"bidamount"}}}}}}`
+
+	return qstr
 }