need rework
This commit is contained in:
parent
4c6649bd30
commit
fac78b1256
@ -29,8 +29,10 @@ func NewClickStatistic(ctx context.Context, deps DepsClick) (*StatisticClick, er
|
||||
}
|
||||
|
||||
// todo toanaliz for keydevice,keydevicetype,keybrowser,
|
||||
// todo получается пока какая то фигня
|
||||
func (s *StatisticClick) checkMW(ctx context.Context) error {
|
||||
// в мат вью получаем последний ссесионный координат, то есть тот момент на котором сессия в квизе завершилась
|
||||
// не зависит какой это тип вопроса, страт, обычный, резулт, получаем всегда последний у сессии
|
||||
// он определят конечное положение пользователя в опросе
|
||||
query := `
|
||||
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_last_answers_events
|
||||
ENGINE = MergeTree()
|
||||
@ -61,57 +63,82 @@ type Statistic struct {
|
||||
type PipeLineStatsResp [][]Statistic
|
||||
|
||||
type FunnelData struct {
|
||||
QuestionID int64
|
||||
Count int64
|
||||
Session string
|
||||
QuestionIDs []int64
|
||||
}
|
||||
|
||||
func (s *StatisticClick) funnelData(ctx context.Context, quizID int64, from uint64, to uint64) ([]FunnelData, error) {
|
||||
query := `
|
||||
SELECT ctxquestionid, uniqExact(ctxsession) AS count
|
||||
FROM mv_last_answers_events
|
||||
WHERE ctxquizid = ? AND event_time BETWEEN ? AND ?
|
||||
GROUP BY ctxquestionid
|
||||
`
|
||||
rows, err := s.conn.QueryContext(ctx, query, quizID, from, to)
|
||||
// получили все уникальные сессии из мат вью
|
||||
sessionQuery := `
|
||||
SELECT DISTINCT ctxsession
|
||||
FROM mv_last_answers_events
|
||||
WHERE ctxquizid = ? AND event_time BETWEEN ? AND ?
|
||||
`
|
||||
sessionRows, err := s.conn.QueryContext(ctx, sessionQuery, quizID, from, to)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var data []FunnelData
|
||||
for rows.Next() {
|
||||
var questionID int64
|
||||
var count int64
|
||||
defer sessionRows.Close()
|
||||
|
||||
err := rows.Scan(&questionID, &count)
|
||||
var funnelData []FunnelData
|
||||
for sessionRows.Next() {
|
||||
var ctxsession string
|
||||
err := sessionRows.Scan(&ctxsession)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// получаем вопросы уникальные, последние в рамках сессии
|
||||
questionQuery := `
|
||||
SELECT DISTINCT ctxquestionid
|
||||
FROM statistics WHERE ctxsession = ? ORDER BY event_time DESC;
|
||||
`
|
||||
questionRows, err := s.conn.QueryContext(ctx, questionQuery, ctxsession)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer questionRows.Close()
|
||||
|
||||
data = append(data, FunnelData{
|
||||
QuestionID: questionID,
|
||||
Count: count,
|
||||
var questions []int64
|
||||
for questionRows.Next() {
|
||||
var ctxquestionid int64
|
||||
err := questionRows.Scan(&ctxquestionid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
questions = append(questions, ctxquestionid)
|
||||
}
|
||||
|
||||
fmt.Println("questions", questions)
|
||||
|
||||
if err := questionRows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
funnelData = append(funnelData, FunnelData{
|
||||
Session: ctxsession,
|
||||
QuestionIDs: questions,
|
||||
})
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
if err := sessionRows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
return funnelData, nil
|
||||
}
|
||||
|
||||
// выборка вопросов с одной воронкой
|
||||
// todo еще раз понять подумать осознать как подписывать воронку сейчас если массив соддержит 1 элемент это старт ответ
|
||||
func (s *StatisticClick) getOneFunnelQuestions(ctx context.Context, quizID int64, from uint64, to uint64) ([]int64, error) {
|
||||
var result []int64
|
||||
|
||||
questionCounts, err := s.funnelData(ctx, quizID, from, to)
|
||||
funnelData, err := s.funnelData(ctx, quizID, from, to)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, qc := range questionCounts {
|
||||
if qc.Count == 1 {
|
||||
result = append(result, qc.QuestionID)
|
||||
for _, fd := range funnelData {
|
||||
if len(fd.QuestionIDs) == 1 {
|
||||
result = append(result, fd.QuestionIDs...)
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,63 +146,60 @@ func (s *StatisticClick) getOneFunnelQuestions(ctx context.Context, quizID int64
|
||||
}
|
||||
|
||||
func (s *StatisticClick) GetPipelinesStatistics(ctx context.Context, quizID int64, from uint64, to uint64) (PipeLineStatsResp, error) {
|
||||
// тут нужно подписать все вопросы, которые принадлежат окончанию сессии, то есть массив ответов до окончания сессии
|
||||
// это делается для каждой из сессии которая имеется в мат вью, это отношение к результату которого достиг респондент
|
||||
|
||||
// для того чтобы получить индентификатор воронки, то есть тот который последний этап прохождения был, то на чем все закончилось
|
||||
// нужно из всех подписанных которые подписываются массивом и нужно выбрать из всех подписанных ответов на вопросы, выбрать те
|
||||
// которые имеет всего один элемент в списке, то есть достижение никакого другого вопроса или результата не проходило через
|
||||
// этот ответа кроме попытки достигнуть этотго оттвета или результата, это и являются конечные точки прохождения вопросов и от них считаются воронки и являются индентификаторами воронки
|
||||
// именно те которые с массивом с 1 элементом
|
||||
|
||||
// нужно вернуть в каждом списке пару, id вопроса и количество ответов на этот вопрос, count - уникальные сессии которые прошли через этот вопрос
|
||||
|
||||
var pipelines PipeLineStatsResp
|
||||
idS, err := s.getOneFunnelQuestions(ctx, quizID, from, to)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query := `
|
||||
SELECT
|
||||
ctxsession,ctxquestionid,count(*) as session_count
|
||||
FROM mv_last_answers_events WHERE ctxquizid = ? AND ctxquestionid = ? AND event_time BETWEEN ? AND ?
|
||||
GROUP BY ctxsession, ctxquestionid ORDER BY ctxsession, ctxquestionid
|
||||
`
|
||||
for _, questionID := range idS {
|
||||
query := `
|
||||
SELECT ctxquestionid, COUNT(DISTINCT ctxsession) AS session_count
|
||||
FROM mv_last_answers_events
|
||||
WHERE ctxquizid = ? AND ctxquestionid = ? AND event_time BETWEEN ? AND ?
|
||||
GROUP BY ctxquestionid
|
||||
`
|
||||
|
||||
for _, quiestionID := range idS {
|
||||
rows, err := s.conn.QueryContext(ctx, query, quizID, quiestionID, from, to)
|
||||
rows, err := s.conn.QueryContext(ctx, query, quizID, questionID, from, to)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var currentPipeline []Statistic
|
||||
var lastSession string
|
||||
|
||||
for rows.Next() {
|
||||
var session string
|
||||
var questionID int64
|
||||
var id int64
|
||||
var count int64
|
||||
err := rows.Scan(&session, &questionID, &count)
|
||||
err := rows.Scan(&id, &count)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// новая сессия - новая воронка
|
||||
if session != lastSession {
|
||||
if lastSession != "" {
|
||||
pipelines = append(pipelines, currentPipeline)
|
||||
}
|
||||
currentPipeline = []Statistic{}
|
||||
}
|
||||
|
||||
// текущая статистика в текущую воронку
|
||||
currentPipeline = append(currentPipeline, Statistic{
|
||||
QuestionID: id,
|
||||
Count: count,
|
||||
QuestionID: questionID,
|
||||
})
|
||||
|
||||
lastSession = session
|
||||
}
|
||||
|
||||
// последня воронка если есть то добавляем
|
||||
if len(currentPipeline) > 0 {
|
||||
pipelines = append(pipelines, currentPipeline)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(currentPipeline) > 0 {
|
||||
pipelines = append(pipelines, currentPipeline)
|
||||
}
|
||||
}
|
||||
|
||||
return pipelines, nil
|
||||
|
||||
Loading…
Reference in New Issue
Block a user