|
@@ -3,11 +3,49 @@ package marketAnalysis
|
|
|
import (
|
|
|
"encoding/json"
|
|
|
"fmt"
|
|
|
- "log"
|
|
|
+ "sort"
|
|
|
"strings"
|
|
|
"util"
|
|
|
)
|
|
|
|
|
|
+const (
|
|
|
+ _ = iota
|
|
|
+ onlyTotal
|
|
|
+ onlyAmount
|
|
|
+ totalAndAmount
|
|
|
+
|
|
|
+ topLimit = 3 //细分市场展示前x个
|
|
|
+)
|
|
|
+
|
|
|
+type scaleRefineRow struct {
|
|
|
+ Total int64 `json:"doc_count"`
|
|
|
+ Amount struct {
|
|
|
+ Value float64 `json:"value"`
|
|
|
+ } `json:"project_amount"`
|
|
|
+ WinnerTotalTop struct {
|
|
|
+ Buckets []struct {
|
|
|
+ Name string `json:"key"`
|
|
|
+ Total int64 `json:"doc_count"`
|
|
|
+ Prop float64 `json:"prop"`
|
|
|
+ } `json:"buckets"`
|
|
|
+ } `json:"winner_total_top"`
|
|
|
+ WinnerAmountTop struct {
|
|
|
+ Buckets []struct {
|
|
|
+ Name string `json:"key"`
|
|
|
+ Amount struct {
|
|
|
+ Value float64 `json:"value"`
|
|
|
+ } `json:"refine_winner_amount"`
|
|
|
+ Prop float64 `json:"prop"`
|
|
|
+ } `json:"buckets"`
|
|
|
+ } `json:"winner_amount_top"`
|
|
|
+ ItemName string `json:"itemName"`
|
|
|
+ UpdateTime int64 `json:"updateTime"`
|
|
|
+}
|
|
|
+
|
|
|
+type scaleRefineData struct {
|
|
|
+ Data []scaleRefineRow
|
|
|
+}
|
|
|
+
|
|
|
//marketScaleRefineQuery 细化聚合
|
|
|
func (mae *MarketAnalysisEntity) marketScaleRefineQuery() (rMap map[string]interface{}, err error) {
|
|
|
//关键词分组聚合
|
|
@@ -21,53 +59,108 @@ func (mae *MarketAnalysisEntity) marketScaleRefineQuery() (rMap map[string]inter
|
|
|
}
|
|
|
}
|
|
|
if len(bools) > 0 {
|
|
|
- aggsGroup = append(aggsGroup, fmt.Sprintf(`"%s":{"filter":{"query":{"bool":{"should":[%s],"minimum_should_match": 1}}},"aggs":{"project_count":{"filter":{}},"project_amount":{"sum":{"field":"sortprice"}},"winner_total_top":{"terms":{"field":"s_winner","order":[{"refine_winner_total":"desc"}],"size":3},"aggs":{"refine_winner_total":{"filter":{}}}},"winner_amount_top":{"terms":{"field":"s_winner","order":[{"refine_winner_amount":"desc"}],"size":3},"aggs":{"refine_winner_amount":{"sum":{"field":"sortprice"}}}}}}`, group.ItemName, strings.Join(bools, ",")))
|
|
|
+ aggsGroup = append(aggsGroup, fmt.Sprintf(`"%s":{"filter":{"query":{"bool":{"should":[%s],"minimum_should_match": 1}}},"aggs":{"project_count":{"filter":{}},"project_amount":{"sum":{"field":"sortprice"}},"winner_total_top":{"terms":{"field":"s_winner","order":[{"refine_winner_total":"desc"}],"size":%d},"aggs":{"refine_winner_total":{"filter":{}}}},"winner_amount_top":{"terms":{"field":"s_winner","order":[{"refine_winner_amount":"desc"}],"size":%d},"aggs":{"refine_winner_amount":{"sum":{"field":"sortprice"}}}}}}`, group.ItemName, strings.Join(bools, ","), topLimit, topLimit))
|
|
|
}
|
|
|
itemDataMap[group.ItemName] = group.UpdateTime
|
|
|
}
|
|
|
finalSql := fmt.Sprintf(mae.GetCommonQuerySqlWithAggs(), strings.Join(aggsGroup, ","))
|
|
|
- log.Printf("final marketScaleRefineQuery sql: %s", finalSql)
|
|
|
|
|
|
rMap = map[string]interface{}{}
|
|
|
- res, docCount := util.GetAggs("projectset", "projectset", finalSql)
|
|
|
+ res, _ := util.GetAggs("projectset", "projectset", finalSql)
|
|
|
if res == nil || len(res) == 0 {
|
|
|
return
|
|
|
}
|
|
|
- log.Println("xxxx", docCount, res)
|
|
|
- type scaleRefineRow struct {
|
|
|
- Total int64 `json:"doc_count"`
|
|
|
- Amount struct {
|
|
|
- Value float64 `json:"value"`
|
|
|
- } `json:"project_amount"`
|
|
|
- WinnerTotalTop []struct {
|
|
|
- Buckets []struct {
|
|
|
- Name string `json:"key"`
|
|
|
- Total int64 `json:"doc_count"`
|
|
|
- } `json:"buckets"`
|
|
|
- } `json:"winner_total_top"`
|
|
|
- WinnerAmountTop []struct {
|
|
|
- Buckets []struct {
|
|
|
- Name string `json:"key"`
|
|
|
- Amount struct {
|
|
|
- Value float64 `json:"value"`
|
|
|
- } `json:"refine_winner_amount"`
|
|
|
- } `json:"buckets"`
|
|
|
- } `json:"winner_amount_top"`
|
|
|
- UpdateTime int64 `json:"updateTime"`
|
|
|
- }
|
|
|
+ scale := scaleRefineData{}
|
|
|
for name, object := range res {
|
|
|
bArr, err := object.MarshalJSON()
|
|
|
if len(bArr) == 0 || err != nil {
|
|
|
continue
|
|
|
}
|
|
|
thisRow := scaleRefineRow{}
|
|
|
- if json.Unmarshal(bArr, &thisRow) != nil {
|
|
|
+ if err := json.Unmarshal(bArr, &thisRow); err != nil {
|
|
|
continue
|
|
|
}
|
|
|
+ thisRow.ItemName = name
|
|
|
thisRow.UpdateTime = itemDataMap[name]
|
|
|
+ scale.Data = append(scale.Data, thisRow)
|
|
|
}
|
|
|
- rMap["scaleRefineAll"] = ""
|
|
|
- rMap["scaleRefineTotalTop"] = ""
|
|
|
- rMap["scaleRefineAmountTop"] = ""
|
|
|
+ //计算占比
|
|
|
+ scale.calculationProp()
|
|
|
+
|
|
|
+ rMap["scaleRefineAll"] = scale.sortBy(totalAndAmount).getFormatTop(-1, totalAndAmount)
|
|
|
+ rMap["scaleRefineTotalTop"] = scale.sortBy(onlyTotal).getFormatTop(topLimit, onlyTotal)
|
|
|
+ rMap["scaleRefineAmountTop"] = scale.sortBy(onlyAmount).getFormatTop(topLimit, onlyAmount)
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
+//calculationProp 计算百分比
|
|
|
+func (srd *scaleRefineData) calculationProp() {
|
|
|
+ for i := 0; i < len(srd.Data); i++ {
|
|
|
+ for m := 0; m < len(srd.Data[i].WinnerAmountTop.Buckets); m++ {
|
|
|
+ srd.Data[i].WinnerAmountTop.Buckets[m].Prop = srd.Data[i].WinnerAmountTop.Buckets[m].Amount.Value / srd.Data[i].Amount.Value
|
|
|
+ }
|
|
|
+ for n := 0; n < len(srd.Data[i].WinnerTotalTop.Buckets); n++ {
|
|
|
+ srd.Data[i].WinnerTotalTop.Buckets[n].Prop = float64(srd.Data[i].WinnerTotalTop.Buckets[n].Total) / float64(srd.Data[i].Total)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//getArrayFormatTop 获取前n个数据,并格式化
|
|
|
+//limit 获取前x条
|
|
|
+//flag 1仅返回数量统计 2仅返回金额统计 3返回数量和金额统计,但不返回各项Top数据
|
|
|
+func (srd *scaleRefineData) getFormatTop(limit, flag int) (rData []map[string]interface{}) {
|
|
|
+ for index, Value := range srd.Data {
|
|
|
+ if index >= limit && limit > -1 {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ thisRow := map[string]interface{}{
|
|
|
+ "name": Value.ItemName,
|
|
|
+ }
|
|
|
+ if flag == 1 || flag == 3 { //返回数量相关数据
|
|
|
+ thisRow["total"] = Value.Total
|
|
|
+ if flag != 3 {
|
|
|
+ topArr := []map[string]interface{}{}
|
|
|
+ for _, v := range Value.WinnerTotalTop.Buckets {
|
|
|
+ topArr = append(topArr, map[string]interface{}{
|
|
|
+ "name": v.Name,
|
|
|
+ "value": v.Total,
|
|
|
+ "prop": v.Prop,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ thisRow["totalTop"] = topArr
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if flag == 2 || flag == 3 { //返回金额相关数据
|
|
|
+ thisRow["amount"] = Value.Amount.Value
|
|
|
+ if flag != 3 {
|
|
|
+ topArr := []map[string]interface{}{}
|
|
|
+ for _, v := range Value.WinnerAmountTop.Buckets {
|
|
|
+ topArr = append(topArr, map[string]interface{}{
|
|
|
+ "name": v.Name,
|
|
|
+ "value": v.Amount.Value,
|
|
|
+ "prop": v.Prop,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ thisRow["amountTop"] = topArr
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rData = append(rData, thisRow)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+//getScaleRefineAll 根据订阅词组创建时间排序
|
|
|
+func (srd *scaleRefineData) sortBy(flag int) *scaleRefineData {
|
|
|
+ sort.Slice(srd.Data, func(i, j int) bool {
|
|
|
+ switch flag {
|
|
|
+ case onlyTotal:
|
|
|
+ return srd.Data[i].Total > srd.Data[j].Total
|
|
|
+ case onlyAmount:
|
|
|
+ return srd.Data[i].Amount.Value > srd.Data[j].Amount.Value
|
|
|
+ case totalAndAmount:
|
|
|
+ return srd.Data[i].UpdateTime > srd.Data[j].UpdateTime
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ })
|
|
|
+ return srd
|
|
|
+}
|