蛋蛋星球 后台端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1380 lines
55 KiB

  1. package egg_energy
  2. import (
  3. md2 "applet/app/md/institutional_management/egg_energy"
  4. "applet/app/utils"
  5. "code.fnuoos.com/EggPlanet/egg_system_rules.git/md"
  6. "code.fnuoos.com/go_rely_warehouse/zyos_go_es.git/es"
  7. "context"
  8. "encoding/json"
  9. "errors"
  10. "fmt"
  11. "github.com/olivere/elastic/v7"
  12. "strconv"
  13. "strings"
  14. )
  15. // 查询Elasticsearch并返回结果
  16. func QueryElasticsearch(req md2.UserEggFlowReq, indexName string) (resp []md2.UserEggFlowReqRespList, total int64, err error) {
  17. // 构建查询条件
  18. boolQuery := elastic.NewBoolQuery()
  19. if req.ScoreValueStart != "" && req.ScoreValueEnd != "" {
  20. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("score_value").Gte(req.ScoreValueStart).Lte(req.ScoreValueEnd))
  21. }
  22. if req.EcpmStart != "" && req.EcpmEnd != "" {
  23. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("ecpm").Gte(req.EcpmStart).Lte(req.EcpmEnd))
  24. }
  25. if req.InviteUserNumsStart != "" && req.InviteUserNumsEnd != "" {
  26. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("invite_user_nums").Gte(req.InviteUserNumsStart).Lte(req.InviteUserNumsEnd))
  27. }
  28. if req.TeamActivityNumsStart != "" && req.TeamActivityNumsEnd != "" {
  29. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("team_activity_nums").Gte(req.TeamActivityNumsStart).Lte(req.TeamActivityNumsEnd))
  30. }
  31. if req.SignInNumsStart != "" && req.SignInNumsEnd != "" {
  32. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("sign_in_nums").Gte(req.SignInNumsStart).Lte(req.SignInNumsEnd))
  33. }
  34. if req.ImActivityNumsStart != "" && req.ImActivityNumsEnd != "" {
  35. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("im_activity_nums").Gte(req.ImActivityNumsStart).Lte(req.ImActivityNumsEnd))
  36. }
  37. if req.SendRedPackageNumsStart != "" && req.SendRedPackageNumsEnd != "" {
  38. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("send_red_package_nums").Gte(req.SendRedPackageNumsStart).Lte(req.SendRedPackageNumsEnd))
  39. }
  40. if req.EggEnergyExchangeAccountBalanceStart != "" && req.EggEnergyExchangeAccountBalanceEnd != "" {
  41. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("egg_energy_exchange_account_balance").Gte(req.EggEnergyExchangeAccountBalanceStart).Lte(req.EggEnergyExchangeAccountBalanceEnd))
  42. }
  43. if req.AccountBalanceExchangeEggEnergyNumsStart != "" && req.AccountBalanceExchangeEggEnergyNumsEnd != "" {
  44. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("account_balance_exchange_egg_energy_nums").Gte(req.AccountBalanceExchangeEggEnergyNumsStart).Lte(req.AccountBalanceExchangeEggEnergyNumsEnd))
  45. }
  46. if req.SendCircleOfFriendNumsStart != "" && req.SendCircleOfFriendNumsEnd != "" {
  47. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("send_circle_of_friend_nums").Gte(req.SendCircleOfFriendNumsStart).Lte(req.SendCircleOfFriendNumsEnd))
  48. }
  49. if req.ForumCommentsNumsStart != "" && req.ForumCommentsNumsEnd != "" {
  50. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("forum_comments_nums").Gte(req.ForumCommentsNumsStart).Lte(req.ForumCommentsNumsEnd))
  51. }
  52. if req.CollegeLearningNumsStart != "" && req.CollegeLearningNumsEnd != "" {
  53. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("college_learning_nums").Gte(req.CollegeLearningNumsStart).Lte(req.CollegeLearningNumsEnd))
  54. }
  55. if req.ViolateNumsStart != "" && req.ViolateNumsEnd != "" {
  56. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("violate_nums").Gte(req.ViolateNumsStart).Lte(req.ViolateNumsEnd))
  57. }
  58. if req.BrowseInterfaceNumsStart != "" && req.BrowseInterfaceNumsEnd != "" {
  59. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("browse_interface_nums").Gte(req.BrowseInterfaceNumsStart).Lte(req.BrowseInterfaceNumsEnd))
  60. }
  61. if req.PersonAddActivityValueStart != "" && req.PersonAddActivityValueEnd != "" {
  62. boolQuery = boolQuery.Filter(elastic.NewRangeQuery("person_add_activity_value").Gte(req.PersonAddActivityValueStart).Lte(req.PersonAddActivityValueEnd))
  63. }
  64. // 执行查询
  65. searchResult, err := es.EsClient.Search().
  66. Index(indexName).
  67. Query(boolQuery).
  68. From((req.Page - 1) * req.PageSize).Size(req.PageSize).
  69. Pretty(true).
  70. Do(context.Background())
  71. if err != nil {
  72. if strings.Contains(err.Error(), "no such index") {
  73. return nil, 0, nil
  74. }
  75. return
  76. }
  77. // 检查是否有结果
  78. if searchResult.Hits.TotalHits.Value == 0 {
  79. return
  80. }
  81. // 解析结果
  82. for _, hit := range searchResult.Hits.Hits {
  83. var doc md2.UserEggFlowReqRespList
  84. err = json.Unmarshal(hit.Source, &doc)
  85. if err != nil {
  86. return
  87. }
  88. resp = append(resp, doc)
  89. }
  90. total = searchResult.Hits.TotalHits.Value
  91. return
  92. }
  93. // StatisticsUserEggScoreValueRange 统计用户蛋蛋分范围
  94. func StatisticsUserEggScoreValueRange(esIndexName string) (resp []map[string]string, err error) {
  95. resp = []map[string]string{}
  96. var result *elastic.SearchResult
  97. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  98. // 1、 创建 extended_stats 高级统计
  99. aggs := elastic.NewExtendedStatsAggregation().Field("score_value")
  100. result, err = es.EsClient.Search().
  101. Index(esIndexName).
  102. TrackTotalHits(true).
  103. Query(boolQuery). // 设置查询条件
  104. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  105. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  106. Pretty(true). // 返回可读的json格式
  107. Do(context.Background())
  108. if err != nil {
  109. return resp, err
  110. }
  111. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  112. agg, found := result.Aggregations.ExtendedStats("result")
  113. if !found {
  114. // 打印结果,注意:这里使用的是取值运算符
  115. return resp, errors.New("未聚合出数据")
  116. }
  117. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  118. //2、histogram 直方图聚合
  119. stdDeviation := *agg.StdDeviation //标准平方差
  120. min := *agg.Min //最小值
  121. max := *agg.Max //最大值
  122. avg := *agg.Avg //平均数
  123. totalCount := agg.Count //总数
  124. discreteCoefficient := stdDeviation / avg //离散系数
  125. newAggs := elastic.NewHistogramAggregation().Field("score_value").Interval(discreteCoefficient).ExtendedBounds(min, max)
  126. searchResult, err := es.EsClient.Search().
  127. Index(esIndexName).
  128. TrackTotalHits(true).
  129. Query(boolQuery). // 设置查询条件
  130. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  131. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  132. Pretty(true). // 返回可读的json格式
  133. Do(context.Background())
  134. if err != nil {
  135. return resp, err
  136. }
  137. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  138. newAgg, found := searchResult.Aggregations.Histogram("result")
  139. if !found {
  140. return resp, errors.New("未聚合出数据")
  141. }
  142. // 3、组装数据
  143. var keys []string
  144. var values []int64
  145. var tempTotalDocCount int64
  146. var endStart, endEnd string
  147. for _, bucket := range newAgg.Buckets {
  148. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  149. if bucket.Key <= stdDeviation {
  150. bucketValue := bucket.Key
  151. keys = append(keys, utils.Float64ToStr(bucketValue))
  152. values = append(values, bucket.DocCount)
  153. } else {
  154. bucketValue := bucket.Key
  155. if tempTotalDocCount == 0 {
  156. endStart = utils.Float64ToStr(bucketValue)
  157. }
  158. tempTotalDocCount += bucket.DocCount
  159. endEnd = utils.Float64ToStr(bucketValue)
  160. }
  161. }
  162. for k, v := range keys {
  163. value, _ := Operate(values[k], totalCount)
  164. if k+1 == len(keys) {
  165. resp = append(resp, map[string]string{
  166. "key": v + " ~ " + utils.AnyToString(max) + " 元",
  167. "value": utils.Float64ToStrPrec10(value),
  168. })
  169. } else {
  170. resp = append(resp, map[string]string{
  171. "key": v + " ~ " + keys[k+1] + " 元",
  172. "value": utils.Float64ToStrPrec10(value),
  173. })
  174. }
  175. }
  176. if tempTotalDocCount > 0 {
  177. temp, _ := Operate(tempTotalDocCount, totalCount)
  178. resp = append(resp, map[string]string{
  179. "key": endStart + " ~ " + endEnd + " 元",
  180. "value": utils.Float64ToStrPrec10(temp),
  181. })
  182. }
  183. }
  184. return resp, nil
  185. }
  186. // StatisticsUserEggKindProportion 统计用户蛋蛋分"评比类型"占比
  187. func StatisticsUserEggKindProportion(esIndexName string) (result []map[string]interface{}, err error) {
  188. var res *elastic.SearchResult
  189. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  190. aggs := elastic.NewTermsAggregation().Field("score_value_kind")
  191. res, err = es.EsClient.Search().
  192. Index(esIndexName).
  193. TrackTotalHits(true).
  194. Query(boolQuery). // 设置查询条件
  195. Aggregation("terms", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  196. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  197. Pretty(true). // 返回可读的json格式
  198. Do(context.Background())
  199. if err != nil {
  200. return result, err
  201. }
  202. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  203. agg, _ := res.Aggregations.Terms("terms")
  204. var total float64
  205. for _, bucket := range agg.Buckets {
  206. var tmp = map[string]interface{}{}
  207. bucketValue := bucket.Key
  208. tmp["key"] = bucketValue
  209. tmp["count"] = bucket.DocCount
  210. switch bucketValue {
  211. case 1:
  212. tmp["name"] = "人工"
  213. break
  214. case 2:
  215. tmp["name"] = "自动"
  216. break
  217. default:
  218. tmp["name"] = "未知"
  219. }
  220. result = append(result, tmp)
  221. total += utils.AnyToFloat64(bucket.DocCount)
  222. }
  223. for _, value := range result {
  224. value["proportion"] = utils.AnyToString(utils.AnyToFloat64(value["count"]) / total)
  225. }
  226. return result, nil
  227. }
  228. // StatisticsUserEggEcpmRange 统计用户"ecpm"范围
  229. func StatisticsUserEggEcpmRange(esIndexName string) (resp []map[string]string, err error) {
  230. resp = []map[string]string{}
  231. var result *elastic.SearchResult
  232. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  233. // 1、 创建 extended_stats 高级统计
  234. aggs := elastic.NewExtendedStatsAggregation().Field("ecpm")
  235. result, err = es.EsClient.Search().
  236. Index(esIndexName).
  237. TrackTotalHits(true).
  238. Query(boolQuery). // 设置查询条件
  239. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  240. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  241. Pretty(true). // 返回可读的json格式
  242. Do(context.Background())
  243. if err != nil {
  244. return resp, err
  245. }
  246. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  247. agg, found := result.Aggregations.ExtendedStats("result")
  248. if !found {
  249. // 打印结果,注意:这里使用的是取值运算符
  250. return resp, errors.New("未聚合出数据")
  251. }
  252. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  253. //2、histogram 直方图聚合
  254. stdDeviation := *agg.StdDeviation //标准平方差
  255. min := *agg.Min //最小值
  256. max := *agg.Max //最大值
  257. avg := *agg.Avg //平均数
  258. totalCount := agg.Count //总数
  259. discreteCoefficient := stdDeviation / avg //离散系数
  260. if stdDeviation < avg {
  261. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  262. discreteCoefficient = stdDeviation
  263. }
  264. newAggs := elastic.NewHistogramAggregation().Field("ecpm").Interval(discreteCoefficient).ExtendedBounds(min, max)
  265. searchResult, err := es.EsClient.Search().
  266. Index(esIndexName).
  267. TrackTotalHits(true).
  268. Query(boolQuery). // 设置查询条件
  269. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  270. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  271. Pretty(true). // 返回可读的json格式
  272. Do(context.Background())
  273. if err != nil {
  274. return resp, err
  275. }
  276. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  277. newAgg, found := searchResult.Aggregations.Histogram("result")
  278. if !found {
  279. return resp, errors.New("未聚合出数据")
  280. }
  281. // 3、组装数据
  282. var keys []string
  283. var values []int64
  284. for _, bucket := range newAgg.Buckets {
  285. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  286. bucketValue := bucket.Key
  287. keys = append(keys, utils.Float64ToStr(bucketValue))
  288. values = append(values, bucket.DocCount)
  289. }
  290. for k, v := range keys {
  291. value, _ := Operate(values[k], totalCount)
  292. if k+1 == len(keys) {
  293. resp = append(resp, map[string]string{
  294. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  295. "value": utils.Float64ToStrPrec10(value),
  296. })
  297. } else {
  298. resp = append(resp, map[string]string{
  299. "key": v + " ~ " + keys[k+1] + " 元",
  300. "value": utils.Float64ToStrPrec10(value),
  301. })
  302. }
  303. }
  304. }
  305. return resp, nil
  306. }
  307. // StatisticsUserEggInviteUserNumsRange 统计用户"拉新人数"范围
  308. func StatisticsUserEggInviteUserNumsRange(esIndexName string) (resp []map[string]string, err error) {
  309. resp = []map[string]string{}
  310. var result *elastic.SearchResult
  311. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  312. // 1、 创建 extended_stats 高级统计
  313. aggs := elastic.NewExtendedStatsAggregation().Field("invite_user_nums")
  314. result, err = es.EsClient.Search().
  315. Index(esIndexName).
  316. TrackTotalHits(true).
  317. Query(boolQuery). // 设置查询条件
  318. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  319. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  320. Pretty(true). // 返回可读的json格式
  321. Do(context.Background())
  322. if err != nil {
  323. return resp, err
  324. }
  325. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  326. agg, found := result.Aggregations.ExtendedStats("result")
  327. if !found {
  328. // 打印结果,注意:这里使用的是取值运算符
  329. return resp, errors.New("未聚合出数据")
  330. }
  331. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  332. //2、histogram 直方图聚合
  333. stdDeviation := *agg.StdDeviation //标准平方差
  334. min := *agg.Min //最小值
  335. max := *agg.Max //最大值
  336. avg := *agg.Avg //平均数
  337. totalCount := agg.Count //总数
  338. discreteCoefficient := stdDeviation / avg //离散系数
  339. if stdDeviation < avg {
  340. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  341. discreteCoefficient = stdDeviation
  342. }
  343. newAggs := elastic.NewHistogramAggregation().Field("invite_user_nums").Interval(discreteCoefficient).ExtendedBounds(min, max)
  344. searchResult, err := es.EsClient.Search().
  345. Index(esIndexName).
  346. TrackTotalHits(true).
  347. Query(boolQuery). // 设置查询条件
  348. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  349. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  350. Pretty(true). // 返回可读的json格式
  351. Do(context.Background())
  352. if err != nil {
  353. return resp, err
  354. }
  355. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  356. newAgg, found := searchResult.Aggregations.Histogram("result")
  357. if !found {
  358. return resp, errors.New("未聚合出数据")
  359. }
  360. // 3、组装数据
  361. var keys []string
  362. var values []int64
  363. for _, bucket := range newAgg.Buckets {
  364. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  365. bucketValue := bucket.Key
  366. keys = append(keys, utils.Float64ToStr(bucketValue))
  367. values = append(values, bucket.DocCount)
  368. }
  369. for k, v := range keys {
  370. value, _ := Operate(values[k], totalCount)
  371. if k+1 == len(keys) {
  372. resp = append(resp, map[string]string{
  373. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  374. "value": utils.Float64ToStrPrec10(value),
  375. })
  376. } else {
  377. resp = append(resp, map[string]string{
  378. "key": v + " ~ " + keys[k+1] + " 元",
  379. "value": utils.Float64ToStrPrec10(value),
  380. })
  381. }
  382. }
  383. }
  384. return resp, nil
  385. }
  386. // StatisticsUserEggTeamActivityNumsRange 统计用户"团队活跃次数"范围
  387. func StatisticsUserEggTeamActivityNumsRange(esIndexName string) (resp []map[string]string, err error) {
  388. resp = []map[string]string{}
  389. var result *elastic.SearchResult
  390. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  391. // 1、 创建 extended_stats 高级统计
  392. aggs := elastic.NewExtendedStatsAggregation().Field("team_activity_nums")
  393. result, err = es.EsClient.Search().
  394. Index(esIndexName).
  395. TrackTotalHits(true).
  396. Query(boolQuery). // 设置查询条件
  397. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  398. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  399. Pretty(true). // 返回可读的json格式
  400. Do(context.Background())
  401. if err != nil {
  402. return resp, err
  403. }
  404. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  405. agg, found := result.Aggregations.ExtendedStats("result")
  406. if !found {
  407. // 打印结果,注意:这里使用的是取值运算符
  408. return resp, errors.New("未聚合出数据")
  409. }
  410. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  411. //2、histogram 直方图聚合
  412. stdDeviation := *agg.StdDeviation //标准平方差
  413. min := *agg.Min //最小值
  414. max := *agg.Max //最大值
  415. avg := *agg.Avg //平均数
  416. totalCount := agg.Count //总数
  417. discreteCoefficient := stdDeviation / avg //离散系数
  418. if stdDeviation < avg {
  419. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  420. discreteCoefficient = stdDeviation
  421. }
  422. newAggs := elastic.NewHistogramAggregation().Field("team_activity_nums").Interval(discreteCoefficient).ExtendedBounds(min, max)
  423. searchResult, err := es.EsClient.Search().
  424. Index(esIndexName).
  425. TrackTotalHits(true).
  426. Query(boolQuery). // 设置查询条件
  427. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  428. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  429. Pretty(true). // 返回可读的json格式
  430. Do(context.Background())
  431. if err != nil {
  432. return resp, err
  433. }
  434. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  435. newAgg, found := searchResult.Aggregations.Histogram("result")
  436. if !found {
  437. return resp, errors.New("未聚合出数据")
  438. }
  439. // 3、组装数据
  440. var keys []string
  441. var values []int64
  442. for _, bucket := range newAgg.Buckets {
  443. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  444. bucketValue := bucket.Key
  445. keys = append(keys, utils.Float64ToStr(bucketValue))
  446. values = append(values, bucket.DocCount)
  447. }
  448. for k, v := range keys {
  449. value, _ := Operate(values[k], totalCount)
  450. if k+1 == len(keys) {
  451. resp = append(resp, map[string]string{
  452. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  453. "value": utils.Float64ToStrPrec10(value),
  454. })
  455. } else {
  456. resp = append(resp, map[string]string{
  457. "key": v + " ~ " + keys[k+1] + " 元",
  458. "value": utils.Float64ToStrPrec10(value),
  459. })
  460. }
  461. }
  462. }
  463. return resp, nil
  464. }
  465. // StatisticsUserEggSignInNumsRange 统计用户"签到次数"范围
  466. func StatisticsUserEggSignInNumsRange(esIndexName string) (resp []map[string]string, err error) {
  467. resp = []map[string]string{}
  468. var result *elastic.SearchResult
  469. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  470. // 1、 创建 extended_stats 高级统计
  471. aggs := elastic.NewExtendedStatsAggregation().Field("sign_in_nums")
  472. result, err = es.EsClient.Search().
  473. Index(esIndexName).
  474. TrackTotalHits(true).
  475. Query(boolQuery). // 设置查询条件
  476. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  477. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  478. Pretty(true). // 返回可读的json格式
  479. Do(context.Background())
  480. if err != nil {
  481. return resp, err
  482. }
  483. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  484. agg, found := result.Aggregations.ExtendedStats("result")
  485. if !found {
  486. // 打印结果,注意:这里使用的是取值运算符
  487. return resp, errors.New("未聚合出数据")
  488. }
  489. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  490. //2、histogram 直方图聚合
  491. stdDeviation := *agg.StdDeviation //标准平方差
  492. min := *agg.Min //最小值
  493. max := *agg.Max //最大值
  494. avg := *agg.Avg //平均数
  495. totalCount := agg.Count //总数
  496. discreteCoefficient := stdDeviation / avg //离散系数
  497. if stdDeviation < avg {
  498. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  499. discreteCoefficient = stdDeviation
  500. }
  501. newAggs := elastic.NewHistogramAggregation().Field("sign_in_nums").Interval(discreteCoefficient).ExtendedBounds(min, max)
  502. searchResult, err := es.EsClient.Search().
  503. Index(esIndexName).
  504. TrackTotalHits(true).
  505. Query(boolQuery). // 设置查询条件
  506. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  507. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  508. Pretty(true). // 返回可读的json格式
  509. Do(context.Background())
  510. if err != nil {
  511. return resp, err
  512. }
  513. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  514. newAgg, found := searchResult.Aggregations.Histogram("result")
  515. if !found {
  516. return resp, errors.New("未聚合出数据")
  517. }
  518. // 3、组装数据
  519. var keys []string
  520. var values []int64
  521. for _, bucket := range newAgg.Buckets {
  522. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  523. bucketValue := bucket.Key
  524. keys = append(keys, utils.Float64ToStr(bucketValue))
  525. values = append(values, bucket.DocCount)
  526. }
  527. for k, v := range keys {
  528. value, _ := Operate(values[k], totalCount)
  529. if k+1 == len(keys) {
  530. resp = append(resp, map[string]string{
  531. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  532. "value": utils.Float64ToStrPrec10(value),
  533. })
  534. } else {
  535. resp = append(resp, map[string]string{
  536. "key": v + " ~ " + keys[k+1] + " 元",
  537. "value": utils.Float64ToStrPrec10(value),
  538. })
  539. }
  540. }
  541. }
  542. return resp, nil
  543. }
  544. // StatisticsUserEggSendRedPackageNumsRange 统计用户"发红包次数"范围
  545. func StatisticsUserEggSendRedPackageNumsRange(esIndexName string) (resp []map[string]string, err error) {
  546. resp = []map[string]string{}
  547. var result *elastic.SearchResult
  548. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  549. // 1、 创建 extended_stats 高级统计
  550. aggs := elastic.NewExtendedStatsAggregation().Field("send_red_package_nums")
  551. result, err = es.EsClient.Search().
  552. Index(esIndexName).
  553. TrackTotalHits(true).
  554. Query(boolQuery). // 设置查询条件
  555. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  556. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  557. Pretty(true). // 返回可读的json格式
  558. Do(context.Background())
  559. if err != nil {
  560. return resp, err
  561. }
  562. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  563. agg, found := result.Aggregations.ExtendedStats("result")
  564. if !found {
  565. // 打印结果,注意:这里使用的是取值运算符
  566. return resp, errors.New("未聚合出数据")
  567. }
  568. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  569. //2、histogram 直方图聚合
  570. stdDeviation := *agg.StdDeviation //标准平方差
  571. min := *agg.Min //最小值
  572. max := *agg.Max //最大值
  573. avg := *agg.Avg //平均数
  574. totalCount := agg.Count //总数
  575. discreteCoefficient := stdDeviation / avg //离散系数
  576. if stdDeviation < avg {
  577. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  578. discreteCoefficient = stdDeviation
  579. }
  580. newAggs := elastic.NewHistogramAggregation().Field("send_red_package_nums").Interval(discreteCoefficient).ExtendedBounds(min, max)
  581. searchResult, err := es.EsClient.Search().
  582. Index(esIndexName).
  583. TrackTotalHits(true).
  584. Query(boolQuery). // 设置查询条件
  585. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  586. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  587. Pretty(true). // 返回可读的json格式
  588. Do(context.Background())
  589. if err != nil {
  590. return resp, err
  591. }
  592. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  593. newAgg, found := searchResult.Aggregations.Histogram("result")
  594. if !found {
  595. return resp, errors.New("未聚合出数据")
  596. }
  597. // 3、组装数据
  598. var keys []string
  599. var values []int64
  600. for _, bucket := range newAgg.Buckets {
  601. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  602. bucketValue := bucket.Key
  603. keys = append(keys, utils.Float64ToStr(bucketValue))
  604. values = append(values, bucket.DocCount)
  605. }
  606. for k, v := range keys {
  607. value, _ := Operate(values[k], totalCount)
  608. if k+1 == len(keys) {
  609. resp = append(resp, map[string]string{
  610. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  611. "value": utils.Float64ToStrPrec10(value),
  612. })
  613. } else {
  614. resp = append(resp, map[string]string{
  615. "key": v + " ~ " + keys[k+1] + " 元",
  616. "value": utils.Float64ToStrPrec10(value),
  617. })
  618. }
  619. }
  620. }
  621. return resp, nil
  622. }
  623. // StatisticsUserEggEggEnergyExchangeAccountBalanceRange 统计用户"蛋蛋能量兑换余额数量"范围
  624. func StatisticsUserEggEggEnergyExchangeAccountBalanceRange(esIndexName string) (resp []map[string]string, err error) {
  625. resp = []map[string]string{}
  626. var result *elastic.SearchResult
  627. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  628. // 1、 创建 extended_stats 高级统计
  629. aggs := elastic.NewExtendedStatsAggregation().Field("account_balance_exchange_egg_energy_nums")
  630. result, err = es.EsClient.Search().
  631. Index(esIndexName).
  632. TrackTotalHits(true).
  633. Query(boolQuery). // 设置查询条件
  634. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  635. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  636. Pretty(true). // 返回可读的json格式
  637. Do(context.Background())
  638. if err != nil {
  639. return resp, err
  640. }
  641. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  642. agg, found := result.Aggregations.ExtendedStats("result")
  643. if !found {
  644. // 打印结果,注意:这里使用的是取值运算符
  645. return resp, errors.New("未聚合出数据")
  646. }
  647. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  648. //2、histogram 直方图聚合
  649. stdDeviation := *agg.StdDeviation //标准平方差
  650. min := *agg.Min //最小值
  651. max := *agg.Max //最大值
  652. avg := *agg.Avg //平均数
  653. totalCount := agg.Count //总数
  654. discreteCoefficient := stdDeviation / avg //离散系数
  655. if stdDeviation < avg {
  656. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  657. discreteCoefficient = stdDeviation
  658. }
  659. newAggs := elastic.NewHistogramAggregation().Field("account_balance_exchange_egg_energy_nums").Interval(discreteCoefficient).ExtendedBounds(min, max)
  660. searchResult, err := es.EsClient.Search().
  661. Index(esIndexName).
  662. TrackTotalHits(true).
  663. Query(boolQuery). // 设置查询条件
  664. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  665. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  666. Pretty(true). // 返回可读的json格式
  667. Do(context.Background())
  668. if err != nil {
  669. return resp, err
  670. }
  671. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  672. newAgg, found := searchResult.Aggregations.Histogram("result")
  673. if !found {
  674. return resp, errors.New("未聚合出数据")
  675. }
  676. // 3、组装数据
  677. var keys []string
  678. var values []int64
  679. for _, bucket := range newAgg.Buckets {
  680. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  681. bucketValue := bucket.Key
  682. keys = append(keys, utils.Float64ToStr(bucketValue))
  683. values = append(values, bucket.DocCount)
  684. }
  685. for k, v := range keys {
  686. value, _ := Operate(values[k], totalCount)
  687. if k+1 == len(keys) {
  688. resp = append(resp, map[string]string{
  689. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  690. "value": utils.Float64ToStrPrec10(value),
  691. })
  692. } else {
  693. resp = append(resp, map[string]string{
  694. "key": v + " ~ " + keys[k+1] + " 元",
  695. "value": utils.Float64ToStrPrec10(value),
  696. })
  697. }
  698. }
  699. }
  700. return resp, nil
  701. }
  702. // StatisticsUserEggAccountBalanceExchangeEggEnergyNumsRange 统计用户"余额兑换蛋蛋能量数量"范围
  703. func StatisticsUserEggAccountBalanceExchangeEggEnergyNumsRange(esIndexName string) (resp []map[string]string, err error) {
  704. resp = []map[string]string{}
  705. var result *elastic.SearchResult
  706. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  707. // 1、 创建 extended_stats 高级统计
  708. aggs := elastic.NewExtendedStatsAggregation().Field("egg_energy_exchange_account_balance")
  709. result, err = es.EsClient.Search().
  710. Index(esIndexName).
  711. TrackTotalHits(true).
  712. Query(boolQuery). // 设置查询条件
  713. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  714. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  715. Pretty(true). // 返回可读的json格式
  716. Do(context.Background())
  717. if err != nil {
  718. return resp, err
  719. }
  720. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  721. agg, found := result.Aggregations.ExtendedStats("result")
  722. if !found {
  723. // 打印结果,注意:这里使用的是取值运算符
  724. return resp, errors.New("未聚合出数据")
  725. }
  726. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  727. //2、histogram 直方图聚合
  728. stdDeviation := *agg.StdDeviation //标准平方差
  729. min := *agg.Min //最小值
  730. max := *agg.Max //最大值
  731. avg := *agg.Avg //平均数
  732. totalCount := agg.Count //总数
  733. discreteCoefficient := stdDeviation / avg //离散系数
  734. if stdDeviation < avg {
  735. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  736. discreteCoefficient = stdDeviation
  737. }
  738. newAggs := elastic.NewHistogramAggregation().Field("egg_energy_exchange_account_balance").Interval(discreteCoefficient).ExtendedBounds(min, max)
  739. searchResult, err := es.EsClient.Search().
  740. Index(esIndexName).
  741. TrackTotalHits(true).
  742. Query(boolQuery). // 设置查询条件
  743. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  744. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  745. Pretty(true). // 返回可读的json格式
  746. Do(context.Background())
  747. if err != nil {
  748. return resp, err
  749. }
  750. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  751. newAgg, found := searchResult.Aggregations.Histogram("result")
  752. if !found {
  753. return resp, errors.New("未聚合出数据")
  754. }
  755. // 3、组装数据
  756. var keys []string
  757. var values []int64
  758. for _, bucket := range newAgg.Buckets {
  759. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  760. bucketValue := bucket.Key
  761. keys = append(keys, utils.Float64ToStr(bucketValue))
  762. values = append(values, bucket.DocCount)
  763. }
  764. for k, v := range keys {
  765. value, _ := Operate(values[k], totalCount)
  766. if k+1 == len(keys) {
  767. resp = append(resp, map[string]string{
  768. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  769. "value": utils.Float64ToStrPrec10(value),
  770. })
  771. } else {
  772. resp = append(resp, map[string]string{
  773. "key": v + " ~ " + keys[k+1] + " 元",
  774. "value": utils.Float64ToStrPrec10(value),
  775. })
  776. }
  777. }
  778. }
  779. return resp, nil
  780. }
  781. // StatisticsUserEggSendCircleOfFriendNumsRange 统计用户"发朋友圈次数"范围
  782. func StatisticsUserEggSendCircleOfFriendNumsRange(esIndexName string) (resp []map[string]string, err error) {
  783. resp = []map[string]string{}
  784. var result *elastic.SearchResult
  785. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  786. // 1、 创建 extended_stats 高级统计
  787. aggs := elastic.NewExtendedStatsAggregation().Field("send_circle_of_friend_nums")
  788. result, err = es.EsClient.Search().
  789. Index(esIndexName).
  790. TrackTotalHits(true).
  791. Query(boolQuery). // 设置查询条件
  792. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  793. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  794. Pretty(true). // 返回可读的json格式
  795. Do(context.Background())
  796. if err != nil {
  797. return resp, err
  798. }
  799. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  800. agg, found := result.Aggregations.ExtendedStats("result")
  801. if !found {
  802. // 打印结果,注意:这里使用的是取值运算符
  803. return resp, errors.New("未聚合出数据")
  804. }
  805. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  806. //2、histogram 直方图聚合
  807. stdDeviation := *agg.StdDeviation //标准平方差
  808. min := *agg.Min //最小值
  809. max := *agg.Max //最大值
  810. avg := *agg.Avg //平均数
  811. totalCount := agg.Count //总数
  812. discreteCoefficient := stdDeviation / avg //离散系数
  813. if stdDeviation < avg {
  814. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  815. discreteCoefficient = stdDeviation
  816. }
  817. newAggs := elastic.NewHistogramAggregation().Field("send_circle_of_friend_nums").Interval(discreteCoefficient).ExtendedBounds(min, max)
  818. searchResult, err := es.EsClient.Search().
  819. Index(esIndexName).
  820. TrackTotalHits(true).
  821. Query(boolQuery). // 设置查询条件
  822. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  823. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  824. Pretty(true). // 返回可读的json格式
  825. Do(context.Background())
  826. if err != nil {
  827. return resp, err
  828. }
  829. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  830. newAgg, found := searchResult.Aggregations.Histogram("result")
  831. if !found {
  832. return resp, errors.New("未聚合出数据")
  833. }
  834. // 3、组装数据
  835. var keys []string
  836. var values []int64
  837. for _, bucket := range newAgg.Buckets {
  838. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  839. bucketValue := bucket.Key
  840. keys = append(keys, utils.Float64ToStr(bucketValue))
  841. values = append(values, bucket.DocCount)
  842. }
  843. for k, v := range keys {
  844. value, _ := Operate(values[k], totalCount)
  845. if k+1 == len(keys) {
  846. resp = append(resp, map[string]string{
  847. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  848. "value": utils.Float64ToStrPrec10(value),
  849. })
  850. } else {
  851. resp = append(resp, map[string]string{
  852. "key": v + " ~ " + keys[k+1] + " 元",
  853. "value": utils.Float64ToStrPrec10(value),
  854. })
  855. }
  856. }
  857. }
  858. return resp, nil
  859. }
  860. // StatisticsUserEggForumCommentsNumsRange 统计用户"论坛评论次数"范围
  861. func StatisticsUserEggForumCommentsNumsRange(esIndexName string) (resp []map[string]string, err error) {
  862. resp = []map[string]string{}
  863. var result *elastic.SearchResult
  864. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  865. // 1、 创建 extended_stats 高级统计
  866. aggs := elastic.NewExtendedStatsAggregation().Field("forum_comments_nums")
  867. result, err = es.EsClient.Search().
  868. Index(esIndexName).
  869. TrackTotalHits(true).
  870. Query(boolQuery). // 设置查询条件
  871. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  872. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  873. Pretty(true). // 返回可读的json格式
  874. Do(context.Background())
  875. if err != nil {
  876. return resp, err
  877. }
  878. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  879. agg, found := result.Aggregations.ExtendedStats("result")
  880. if !found {
  881. // 打印结果,注意:这里使用的是取值运算符
  882. return resp, errors.New("未聚合出数据")
  883. }
  884. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  885. //2、histogram 直方图聚合
  886. stdDeviation := *agg.StdDeviation //标准平方差
  887. min := *agg.Min //最小值
  888. max := *agg.Max //最大值
  889. avg := *agg.Avg //平均数
  890. totalCount := agg.Count //总数
  891. discreteCoefficient := stdDeviation / avg //离散系数
  892. if stdDeviation < avg {
  893. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  894. discreteCoefficient = stdDeviation
  895. }
  896. newAggs := elastic.NewHistogramAggregation().Field("forum_comments_nums").Interval(discreteCoefficient).ExtendedBounds(min, max)
  897. searchResult, err := es.EsClient.Search().
  898. Index(esIndexName).
  899. TrackTotalHits(true).
  900. Query(boolQuery). // 设置查询条件
  901. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  902. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  903. Pretty(true). // 返回可读的json格式
  904. Do(context.Background())
  905. if err != nil {
  906. return resp, err
  907. }
  908. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  909. newAgg, found := searchResult.Aggregations.Histogram("result")
  910. if !found {
  911. return resp, errors.New("未聚合出数据")
  912. }
  913. // 3、组装数据
  914. var keys []string
  915. var values []int64
  916. for _, bucket := range newAgg.Buckets {
  917. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  918. bucketValue := bucket.Key
  919. keys = append(keys, utils.Float64ToStr(bucketValue))
  920. values = append(values, bucket.DocCount)
  921. }
  922. for k, v := range keys {
  923. value, _ := Operate(values[k], totalCount)
  924. if k+1 == len(keys) {
  925. resp = append(resp, map[string]string{
  926. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  927. "value": utils.Float64ToStrPrec10(value),
  928. })
  929. } else {
  930. resp = append(resp, map[string]string{
  931. "key": v + " ~ " + keys[k+1] + " 元",
  932. "value": utils.Float64ToStrPrec10(value),
  933. })
  934. }
  935. }
  936. }
  937. return resp, nil
  938. }
  939. // StatisticsUserEggCollegeLearningNumsRange 统计用户"学院学习次数"范围
  940. func StatisticsUserEggCollegeLearningNumsRange(esIndexName string) (resp []map[string]string, err error) {
  941. resp = []map[string]string{}
  942. var result *elastic.SearchResult
  943. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  944. // 1、 创建 extended_stats 高级统计
  945. aggs := elastic.NewExtendedStatsAggregation().Field("college_learning_nums")
  946. result, err = es.EsClient.Search().
  947. Index(esIndexName).
  948. TrackTotalHits(true).
  949. Query(boolQuery). // 设置查询条件
  950. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  951. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  952. Pretty(true). // 返回可读的json格式
  953. Do(context.Background())
  954. if err != nil {
  955. return resp, err
  956. }
  957. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  958. agg, found := result.Aggregations.ExtendedStats("result")
  959. if !found {
  960. // 打印结果,注意:这里使用的是取值运算符
  961. return resp, errors.New("未聚合出数据")
  962. }
  963. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  964. //2、histogram 直方图聚合
  965. stdDeviation := *agg.StdDeviation //标准平方差
  966. min := *agg.Min //最小值
  967. max := *agg.Max //最大值
  968. avg := *agg.Avg //平均数
  969. totalCount := agg.Count //总数
  970. discreteCoefficient := stdDeviation / avg //离散系数
  971. if stdDeviation < avg {
  972. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  973. discreteCoefficient = stdDeviation
  974. }
  975. newAggs := elastic.NewHistogramAggregation().Field("college_learning_nums").Interval(discreteCoefficient).ExtendedBounds(min, max)
  976. searchResult, err := es.EsClient.Search().
  977. Index(esIndexName).
  978. TrackTotalHits(true).
  979. Query(boolQuery). // 设置查询条件
  980. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  981. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  982. Pretty(true). // 返回可读的json格式
  983. Do(context.Background())
  984. if err != nil {
  985. return resp, err
  986. }
  987. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  988. newAgg, found := searchResult.Aggregations.Histogram("result")
  989. if !found {
  990. return resp, errors.New("未聚合出数据")
  991. }
  992. // 3、组装数据
  993. var keys []string
  994. var values []int64
  995. for _, bucket := range newAgg.Buckets {
  996. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  997. bucketValue := bucket.Key
  998. keys = append(keys, utils.Float64ToStr(bucketValue))
  999. values = append(values, bucket.DocCount)
  1000. }
  1001. for k, v := range keys {
  1002. value, _ := Operate(values[k], totalCount)
  1003. if k+1 == len(keys) {
  1004. resp = append(resp, map[string]string{
  1005. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  1006. "value": utils.Float64ToStrPrec10(value),
  1007. })
  1008. } else {
  1009. resp = append(resp, map[string]string{
  1010. "key": v + " ~ " + keys[k+1] + " 元",
  1011. "value": utils.Float64ToStrPrec10(value),
  1012. })
  1013. }
  1014. }
  1015. }
  1016. return resp, nil
  1017. }
  1018. // StatisticsUserEggViolateNumsRange 统计用户"违规次数"范围
  1019. func StatisticsUserEggViolateNumsRange(esIndexName string) (resp []map[string]string, err error) {
  1020. resp = []map[string]string{}
  1021. var result *elastic.SearchResult
  1022. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  1023. // 1、 创建 extended_stats 高级统计
  1024. aggs := elastic.NewExtendedStatsAggregation().Field("violate_nums")
  1025. result, err = es.EsClient.Search().
  1026. Index(esIndexName).
  1027. TrackTotalHits(true).
  1028. Query(boolQuery). // 设置查询条件
  1029. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  1030. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  1031. Pretty(true). // 返回可读的json格式
  1032. Do(context.Background())
  1033. if err != nil {
  1034. return resp, err
  1035. }
  1036. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  1037. agg, found := result.Aggregations.ExtendedStats("result")
  1038. if !found {
  1039. // 打印结果,注意:这里使用的是取值运算符
  1040. return resp, errors.New("未聚合出数据")
  1041. }
  1042. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  1043. //2、histogram 直方图聚合
  1044. stdDeviation := *agg.StdDeviation //标准平方差
  1045. min := *agg.Min //最小值
  1046. max := *agg.Max //最大值
  1047. avg := *agg.Avg //平均数
  1048. totalCount := agg.Count //总数
  1049. discreteCoefficient := stdDeviation / avg //离散系数
  1050. if stdDeviation < avg {
  1051. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  1052. discreteCoefficient = stdDeviation
  1053. }
  1054. newAggs := elastic.NewHistogramAggregation().Field("violate_nums").Interval(discreteCoefficient).ExtendedBounds(min, max)
  1055. searchResult, err := es.EsClient.Search().
  1056. Index(esIndexName).
  1057. TrackTotalHits(true).
  1058. Query(boolQuery). // 设置查询条件
  1059. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  1060. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  1061. Pretty(true). // 返回可读的json格式
  1062. Do(context.Background())
  1063. if err != nil {
  1064. return resp, err
  1065. }
  1066. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  1067. newAgg, found := searchResult.Aggregations.Histogram("result")
  1068. if !found {
  1069. return resp, errors.New("未聚合出数据")
  1070. }
  1071. // 3、组装数据
  1072. var keys []string
  1073. var values []int64
  1074. for _, bucket := range newAgg.Buckets {
  1075. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  1076. bucketValue := bucket.Key
  1077. keys = append(keys, utils.Float64ToStr(bucketValue))
  1078. values = append(values, bucket.DocCount)
  1079. }
  1080. for k, v := range keys {
  1081. value, _ := Operate(values[k], totalCount)
  1082. if k+1 == len(keys) {
  1083. resp = append(resp, map[string]string{
  1084. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  1085. "value": utils.Float64ToStrPrec10(value),
  1086. })
  1087. } else {
  1088. resp = append(resp, map[string]string{
  1089. "key": v + " ~ " + keys[k+1] + " 元",
  1090. "value": utils.Float64ToStrPrec10(value),
  1091. })
  1092. }
  1093. }
  1094. }
  1095. return resp, nil
  1096. }
  1097. // StatisticsUserEggBrowseInterfaceNumsRange 统计用户"浏览界面次数"范围
  1098. func StatisticsUserEggBrowseInterfaceNumsRange(esIndexName string) (resp []map[string]string, err error) {
  1099. resp = []map[string]string{}
  1100. var result *elastic.SearchResult
  1101. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  1102. // 1、 创建 extended_stats 高级统计
  1103. aggs := elastic.NewExtendedStatsAggregation().Field("browse_interface_nums")
  1104. result, err = es.EsClient.Search().
  1105. Index(esIndexName).
  1106. TrackTotalHits(true).
  1107. Query(boolQuery). // 设置查询条件
  1108. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  1109. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  1110. Pretty(true). // 返回可读的json格式
  1111. Do(context.Background())
  1112. if err != nil {
  1113. return resp, err
  1114. }
  1115. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  1116. agg, found := result.Aggregations.ExtendedStats("result")
  1117. if !found {
  1118. // 打印结果,注意:这里使用的是取值运算符
  1119. return resp, errors.New("未聚合出数据")
  1120. }
  1121. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  1122. //2、histogram 直方图聚合
  1123. stdDeviation := *agg.StdDeviation //标准平方差
  1124. min := *agg.Min //最小值
  1125. max := *agg.Max //最大值
  1126. avg := *agg.Avg //平均数
  1127. totalCount := agg.Count //总数
  1128. discreteCoefficient := stdDeviation / avg //离散系数
  1129. if stdDeviation < avg {
  1130. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  1131. discreteCoefficient = stdDeviation
  1132. }
  1133. newAggs := elastic.NewHistogramAggregation().Field("browse_interface_nums").Interval(discreteCoefficient).ExtendedBounds(min, max)
  1134. searchResult, err := es.EsClient.Search().
  1135. Index(esIndexName).
  1136. TrackTotalHits(true).
  1137. Query(boolQuery). // 设置查询条件
  1138. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  1139. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  1140. Pretty(true). // 返回可读的json格式
  1141. Do(context.Background())
  1142. if err != nil {
  1143. return resp, err
  1144. }
  1145. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  1146. newAgg, found := searchResult.Aggregations.Histogram("result")
  1147. if !found {
  1148. return resp, errors.New("未聚合出数据")
  1149. }
  1150. // 3、组装数据
  1151. var keys []string
  1152. var values []int64
  1153. for _, bucket := range newAgg.Buckets {
  1154. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  1155. bucketValue := bucket.Key
  1156. keys = append(keys, utils.Float64ToStr(bucketValue))
  1157. values = append(values, bucket.DocCount)
  1158. }
  1159. for k, v := range keys {
  1160. value, _ := Operate(values[k], totalCount)
  1161. if k+1 == len(keys) {
  1162. resp = append(resp, map[string]string{
  1163. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  1164. "value": utils.Float64ToStrPrec10(value),
  1165. })
  1166. } else {
  1167. resp = append(resp, map[string]string{
  1168. "key": v + " ~ " + keys[k+1] + " 元",
  1169. "value": utils.Float64ToStrPrec10(value),
  1170. })
  1171. }
  1172. }
  1173. }
  1174. return resp, nil
  1175. }
  1176. // StatisticsUserEggPersonAddActivityValueRange 统计用户"个人活跃积分增量值"范围
  1177. func StatisticsUserEggPersonAddActivityValueRange(esIndexName string) (resp []map[string]string, err error) {
  1178. resp = []map[string]string{}
  1179. var result *elastic.SearchResult
  1180. boolQuery := elastic.NewBoolQuery().Must() // 创建bool查询
  1181. // 1、 创建 extended_stats 高级统计
  1182. aggs := elastic.NewExtendedStatsAggregation().Field("person_add_activity_value")
  1183. result, err = es.EsClient.Search().
  1184. Index(esIndexName).
  1185. TrackTotalHits(true).
  1186. Query(boolQuery). // 设置查询条件
  1187. Aggregation("result", aggs). // 设置聚合条件,并为聚合条件设置一个名字
  1188. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  1189. Pretty(true). // 返回可读的json格式
  1190. Do(context.Background())
  1191. if err != nil {
  1192. return resp, err
  1193. }
  1194. // 使用Cardinality函数和前面定义的聚合条件名称,查询结果
  1195. agg, found := result.Aggregations.ExtendedStats("result")
  1196. if !found {
  1197. // 打印结果,注意:这里使用的是取值运算符
  1198. return resp, errors.New("未聚合出数据")
  1199. }
  1200. if agg.StdDeviation != nil && *agg.StdDeviation != 0 {
  1201. //2、histogram 直方图聚合
  1202. stdDeviation := *agg.StdDeviation //标准平方差
  1203. min := *agg.Min //最小值
  1204. max := *agg.Max //最大值
  1205. avg := *agg.Avg //平均数
  1206. totalCount := agg.Count //总数
  1207. discreteCoefficient := stdDeviation / avg //离散系数
  1208. if stdDeviation < avg {
  1209. //TODO::如果标准差相对较小,而平均值较大,离散系数可能会导致较大的间隔,直接使用标准差或其他更合适的值作为间隔。
  1210. discreteCoefficient = stdDeviation
  1211. }
  1212. newAggs := elastic.NewHistogramAggregation().Field("person_add_activity_value").Interval(discreteCoefficient).ExtendedBounds(min, max)
  1213. searchResult, err := es.EsClient.Search().
  1214. Index(esIndexName).
  1215. TrackTotalHits(true).
  1216. Query(boolQuery). // 设置查询条件
  1217. Aggregation("result", newAggs). // 设置聚合条件,并为聚合条件设置一个名字
  1218. Size(0). // 设置分页参数 - 每页大小,设置为0,代表不返回搜索结果,仅返回聚合分析结果
  1219. Pretty(true). // 返回可读的json格式
  1220. Do(context.Background())
  1221. if err != nil {
  1222. return resp, err
  1223. }
  1224. // 使用Terms函数和前面定义的聚合条件名称,查询结果
  1225. newAgg, found := searchResult.Aggregations.Histogram("result")
  1226. if !found {
  1227. return resp, errors.New("未聚合出数据")
  1228. }
  1229. // 3、组装数据
  1230. var keys []string
  1231. var values []int64
  1232. for _, bucket := range newAgg.Buckets {
  1233. // 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
  1234. bucketValue := bucket.Key
  1235. keys = append(keys, utils.Float64ToStr(bucketValue))
  1236. values = append(values, bucket.DocCount)
  1237. }
  1238. for k, v := range keys {
  1239. value, _ := Operate(values[k], totalCount)
  1240. if k+1 == len(keys) {
  1241. resp = append(resp, map[string]string{
  1242. "key": v + " ~ " + utils.Float64ToStr(max) + " 元",
  1243. "value": utils.Float64ToStrPrec10(value),
  1244. })
  1245. } else {
  1246. resp = append(resp, map[string]string{
  1247. "key": v + " ~ " + keys[k+1] + " 元",
  1248. "value": utils.Float64ToStrPrec10(value),
  1249. })
  1250. }
  1251. }
  1252. }
  1253. return resp, nil
  1254. }
  1255. func GetYearsAndWeeks() (resp map[string][]string, err error) {
  1256. // 1、 获取到所有的索引
  1257. indices, err := es.GetIndexFromAlias(md.EggEnergyUserEggScoreEsAlias)
  1258. if err != nil {
  1259. return nil, err
  1260. }
  1261. //2、组装数据
  1262. resp = map[string][]string{}
  1263. for _, index := range indices {
  1264. // 分割字符串
  1265. parts := strings.Split(index, "_")
  1266. // 提取 2024 和 46
  1267. resp[parts[len(parts)-1][:4]] = append(resp[parts[len(parts)-1][:4]], parts[len(parts)-1][4:])
  1268. }
  1269. return
  1270. }
  1271. func GetYearsAndWeekStr(esIndexName string) (string, string) {
  1272. parts := strings.Split(esIndexName, "_")
  1273. return parts[len(parts)-1][:4], parts[len(parts)-1][4:]
  1274. }
  1275. // Operate 除运算保留10位小数
  1276. func Operate(num1, num2 int64) (float64, error) {
  1277. value, err := strconv.ParseFloat(fmt.Sprintf("%.10f", float64(num1)/float64(num2)), 64)
  1278. if err != nil {
  1279. return 0, err
  1280. }
  1281. return value, nil
  1282. }