2022-01-26 16:40:50 +08:00
|
|
|
package analysis
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/1340691923/xwl_bi/engine/db"
|
|
|
|
"github.com/1340691923/xwl_bi/engine/logs"
|
|
|
|
"github.com/1340691923/xwl_bi/platform-basic-libs/my_error"
|
|
|
|
"github.com/1340691923/xwl_bi/platform-basic-libs/request"
|
|
|
|
"github.com/1340691923/xwl_bi/platform-basic-libs/service/analysis/utils"
|
|
|
|
"github.com/1340691923/xwl_bi/platform-basic-libs/service/meta_data"
|
|
|
|
jsoniter "github.com/json-iterator/go"
|
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Trace struct {
|
|
|
|
sql string
|
|
|
|
args []interface{}
|
|
|
|
eventNameMapStr string
|
|
|
|
req request.TraceReqData
|
|
|
|
sqlTyp int
|
|
|
|
}
|
|
|
|
|
|
|
|
const ChartSql int = 1
|
|
|
|
|
|
|
|
const TableSql int = 2
|
|
|
|
|
|
|
|
func (this *Trace) setSqlTyp(typ int) {
|
|
|
|
this.sqlTyp = typ
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (this *Trace) GetList() (interface{}, error) {
|
|
|
|
|
|
|
|
type Res1 struct {
|
|
|
|
Source string `json:"source"`
|
|
|
|
Target string `json:"target"`
|
|
|
|
Value int `json:"value"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Res2 struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.setSqlTyp(TableSql)
|
|
|
|
|
|
|
|
SQL, args, err := this.GetExecSql()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
logs.Logger.Sugar().Infof("sql", SQL, args, err)
|
|
|
|
|
|
|
|
type TableRes struct {
|
|
|
|
Trace string `json:"trace" db:"trace"`
|
|
|
|
UserCount uint64 `json:"user_count" db:"user_count"`
|
|
|
|
Ui []string `json:"ui" db:"ui"`
|
|
|
|
}
|
|
|
|
|
|
|
|
var tableRes []TableRes
|
|
|
|
|
|
|
|
err = db.ClickHouseSqlx.Select(&tableRes, SQL, args...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setSqlTyp(ChartSql)
|
|
|
|
|
|
|
|
SQL, args, err = this.GetExecSql()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
logs.Logger.Sugar().Infof("sql", SQL, args, err)
|
|
|
|
|
|
|
|
type ChartsRes struct {
|
|
|
|
Event []string `json:"event" db:"trace2"`
|
|
|
|
SumUserCount uint64 `json:"sum_user_count" db:"sum_user_count"`
|
|
|
|
}
|
|
|
|
|
|
|
|
var chartsRes []ChartsRes
|
|
|
|
|
|
|
|
err = db.ClickHouseSqlx.Select(&chartsRes, SQL, args...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return map[string]interface{}{"tableRes": tableRes, "chartRes": chartsRes}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *Trace) GetTableSql() (SQL string, allArgs []interface{}, err error) {
|
|
|
|
startTime := this.req.Date[0] + " 00:00:00"
|
|
|
|
endTime := this.req.Date[1] + " 23:59:59"
|
|
|
|
|
|
|
|
windowSql, allArgs, err := getZhibiaoFilterSqlArgs(this.req.ZhibiaoArr)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
userFilterSql, userFilterArgs, err := getUserfilterSqlArgs(this.req.WhereFilterByUser, this.req.Appid)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
whereFilterSql, whereFilterArgs, _, err := utils.GetWhereSql(this.req.WhereFilter)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(this.req.EventNames) > 1 {
|
|
|
|
whereFilterSql = whereFilterSql + " and xwl_part_event in (?) "
|
|
|
|
whereFilterArgs = append(whereFilterArgs, this.req.EventNames)
|
|
|
|
}
|
|
|
|
|
|
|
|
whereFilterSql = whereFilterSql + this.sql
|
|
|
|
|
|
|
|
allArgs = append(allArgs, whereFilterArgs...)
|
|
|
|
|
2022-03-09 11:56:26 +08:00
|
|
|
allArgs = append(allArgs, this.args...)
|
|
|
|
|
2022-01-26 16:40:50 +08:00
|
|
|
allArgs = append(allArgs, userFilterArgs...)
|
|
|
|
|
|
|
|
SQL = `
|
|
|
|
select trace ,user_count,ui from (SELECT
|
|
|
|
result_chain as trace,
|
|
|
|
uniqCombined(user_id) AS user_count,groupUniqArray(user_id) ui
|
|
|
|
FROM (
|
|
|
|
select
|
|
|
|
xwl_distinct_id as user_id,
|
|
|
|
` + this.eventNameMapStr + ` as eventMap,
|
|
|
|
arrayStringConcat(
|
|
|
|
arrayCompact(
|
|
|
|
arrayMap(
|
|
|
|
b -> tupleElement(b, 1),
|
|
|
|
arraySort(
|
|
|
|
y -> tupleElement(y, 2),
|
|
|
|
arrayFilter(
|
|
|
|
(x, y) -> y - x.2 <= ` + strconv.Itoa(this.req.WindowTime) + ` and y - x.2 >= 0,
|
|
|
|
arrayMap(
|
|
|
|
(x, y) -> (x, y),
|
|
|
|
groupArray(mapValues(eventMap)[indexOf(mapKeys(eventMap), xwl_part_event)]),
|
|
|
|
groupArray(toUnixTimestamp(xwl_part_date))
|
|
|
|
),
|
|
|
|
arrayWithConstant(
|
|
|
|
length(groupArray(toUnixTimestamp(xwl_part_date))),
|
|
|
|
maxIf(toUnixTimestamp(xwl_part_date) ` + windowSql + `)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
),
|
|
|
|
'->'
|
|
|
|
) result_chain
|
|
|
|
from
|
|
|
|
xwl_event` + strconv.Itoa(this.req.Appid) + `
|
|
|
|
prewhere
|
|
|
|
xwl_part_date >= toDateTime('` + startTime + `')
|
|
|
|
AND xwl_part_date <= toDateTime('` + endTime + `') and ` + whereFilterSql + ` ` + userFilterSql + `
|
|
|
|
|
|
|
|
group by
|
|
|
|
xwl_distinct_id
|
|
|
|
HAVING notEmpty(result_chain)
|
|
|
|
) tab
|
|
|
|
GROUP BY result_chain
|
|
|
|
ORDER BY user_count DESC) limit 1000
|
|
|
|
`
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (this *Trace) GetChartSql() (SQL string, allArgs []interface{}, err error) {
|
|
|
|
startTime := this.req.Date[0] + " 00:00:00"
|
|
|
|
endTime := this.req.Date[1] + " 23:59:59"
|
|
|
|
|
|
|
|
windowSql, allArgs, err := getZhibiaoFilterSqlArgs(this.req.ZhibiaoArr)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
userFilterSql, userFilterArgs, err := getUserfilterSqlArgs(this.req.WhereFilterByUser, this.req.Appid)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
whereFilterSql, whereFilterArgs, _, err := utils.GetWhereSql(this.req.WhereFilter)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(this.req.EventNames) > 1 {
|
|
|
|
whereFilterSql = whereFilterSql + " and xwl_part_event in (?) "
|
|
|
|
whereFilterArgs = append(whereFilterArgs, this.req.EventNames)
|
|
|
|
}
|
|
|
|
|
|
|
|
whereFilterSql = whereFilterSql + this.sql
|
|
|
|
|
|
|
|
allArgs = append(allArgs, whereFilterArgs...)
|
|
|
|
|
|
|
|
allArgs = append(allArgs, this.args...)
|
|
|
|
|
|
|
|
allArgs = append(allArgs, userFilterArgs...)
|
|
|
|
|
|
|
|
SQL = `select splitByString('->', arrayJoin(arrayMap( (x, y) -> concat(concat( x,'->'),y),arraySlice(trace, 1, length(trace) - 1),arraySlice(trace, 2, length(trace)) ))) as trace2,sum(1) as sum_user_count from (
|
|
|
|
|
|
|
|
select if(length(trace33)==1,arrayPushBack(trace33,str_link),arrayPushBack(arraySlice(trace33, 1, length(trace33) - 1),str_link)) as trace from (
|
|
|
|
select arrayMap((x, y) -> CONCAT(x, concat('(',concat(toString(y),')'))),result_chain,arrayEnumerateUniq(result_chain)) as trace33,concat(mapValues(eventMap)[indexOf(mapKeys(eventMap), '`+this.req.ZhibiaoArr[0].EventName+`')],'(最终路径)') as str_link from (
|
|
|
|
|
|
|
|
select
|
|
|
|
xwl_distinct_id as user_id, ` + this.eventNameMapStr + ` as eventMap,
|
|
|
|
|
|
|
|
arrayCompact(
|
|
|
|
arrayMap(
|
|
|
|
b -> tupleElement(b, 1),
|
|
|
|
arraySort(
|
|
|
|
y -> tupleElement(y, 2),
|
|
|
|
arrayFilter(
|
|
|
|
(x, y) -> y - x.2 <= ` + strconv.Itoa(this.req.WindowTime) + ` and y - x.2 >= 0,
|
|
|
|
arrayMap(
|
|
|
|
(x, y) -> (x, y),
|
|
|
|
groupArray(mapValues(eventMap)[indexOf(mapKeys(eventMap), xwl_part_event)]),
|
|
|
|
groupArray(toUnixTimestamp(xwl_part_date))
|
|
|
|
),
|
|
|
|
arrayWithConstant(
|
|
|
|
length(groupArray(toUnixTimestamp(xwl_part_date))),
|
|
|
|
maxIf(toUnixTimestamp(xwl_part_date)` + windowSql + ` )
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
result_chain
|
|
|
|
from
|
|
|
|
xwl_event` + strconv.Itoa(this.req.Appid) + `
|
|
|
|
prewhere
|
|
|
|
xwl_part_date >= toDateTime('` + startTime + `')
|
|
|
|
AND xwl_part_date <= toDateTime('` + endTime + `') and ` + whereFilterSql + ` ` + userFilterSql + `
|
|
|
|
group by
|
|
|
|
xwl_distinct_id
|
|
|
|
HAVING notEmpty(result_chain)
|
|
|
|
|
|
|
|
)))
|
|
|
|
|
|
|
|
group by trace2
|
|
|
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (this *Trace) GetExecSql() (SQL string, allArgs []interface{}, err error) {
|
|
|
|
if this.sqlTyp == ChartSql {
|
|
|
|
return this.GetChartSql()
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.GetTableSql()
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewTrace(reqData []byte) (Ianalysis, error) {
|
|
|
|
obj := &Trace{}
|
|
|
|
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
|
|
|
err := json.Unmarshal(reqData, &obj.req)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if len(obj.req.Date) < 2 {
|
|
|
|
return nil, my_error.NewBusiness(ERROR_TABLE, TimeError)
|
|
|
|
}
|
|
|
|
if len(obj.req.ZhibiaoArr) != 1 {
|
|
|
|
return nil, my_error.NewBusiness(ERROR_TABLE, ZhiBiaoNumError)
|
|
|
|
}
|
|
|
|
obj.sqlTyp = TableSql
|
|
|
|
var T int
|
|
|
|
switch obj.req.WindowTimeFormat {
|
|
|
|
case "天":
|
|
|
|
T = 60 * 60 * 24
|
|
|
|
case "小时":
|
|
|
|
T = 60 * 60
|
|
|
|
case "分钟":
|
|
|
|
T = 60
|
|
|
|
case "秒":
|
|
|
|
T = 1
|
|
|
|
default:
|
|
|
|
return nil, my_error.NewBusiness(ERROR_TABLE, TimeError)
|
|
|
|
}
|
|
|
|
obj.req.WindowTime = obj.req.WindowTime * T
|
|
|
|
metaDataService := meta_data.MetaDataService{Appid: strconv.Itoa(obj.req.Appid)}
|
|
|
|
mapStr, err := metaDataService.GetEventNameShowMap()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
obj.eventNameMapStr = mapStr
|
|
|
|
|
|
|
|
obj.sql, obj.args, err = utils.GetUserGroupSqlAndArgs(obj.req.UserGroup, obj.req.Appid)
|
2022-03-09 11:56:26 +08:00
|
|
|
|
|
|
|
|
2022-01-26 16:40:50 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
obj.req.EventNames = append(obj.req.EventNames, obj.req.ZhibiaoArr[0].EventName)
|
|
|
|
|
|
|
|
return obj, nil
|
|
|
|
}
|