---
# System prepended metadata

title: Сбор статистики

---

Сбор статистики
===

### Схема запроса
```json
{
  "tracks": [
    {
      "start": "2019-03-13T12:00:00Z",
      "end": "2019-03-13T12:05:00Z",
      "visitor": {
        "id": "CCC",
        "gender": "male",
        "camera_resolution": "100x100",
        "identity_type": "person",
        "quality": 0.82,
        "age": 32,
        "age_variation": 5,
        "ethnicity": "caucasian",
        "glasses": "dark",
        "facial_hair": "beard",
        "hair_color": "gray",
        "hair_type": "normal",
        "headwear": "cap",
        "attributes": {
          "emotions": [
            {
              "value": "neutral",
              "time": 10
            },
            {
              "value": "neutral",
              "time": 20
            }
          ],
          "smile": [
            {
              "value": "no",
              "time": 10
            },
            {
              "value": "yes",
              "time": 20
            }
          ],
          "pitch": [
            {
              "value": 10,
              "time": 10
            },
            {
              "value": -40,
              "time": 20
            }
          ],
          "yaw": [
            {
              "value": -20,
              "time": 10
            },
            {
              "value": 30,
              "time": 20
            }
          ],
          "x": [
            {
              "value": 0.5,
              "time": 10
            },
            {
              "value": 0.8,
              "time": 20
            }
          ],
          "y": [
            {
              "value": 0.5,
              "time": 10
            },
            {
              "value": 0.8,
              "time": 20
            }
          ],
          "height": [
            {
              "value": 0.6,
              "time": 10
            },
            {
              "value": 0.9,
              "time": 20
            }
          ]
        },
        "merge": [
          "AAA",
          "BBB"
        ]
      },
      "views": [
        {
          "campaign_id": 10,
          "content_id": 10,
          "content_session_id": "331c6883dd6010864b7ead130be77cd5",
          "campaign_content_id": 1,
          "campaign_session_id": "3fbc5f926840bfe1733b70cbca82c0ab",
           "adblock_id" : 1101,
           "adblock_session_id" : "3fbc5f926840bfe1733b70cbca82c0ab",
          "start": "2019-03-13T12:01:00Z",
          "end": "2019-03-13T12:02:00Z"
        }
      ]
    }
  ],
  "shows": [
    {
      "campaign_id": 10,
      "campaign_content_id": 1,
      "campaign_session_id": "3fbc5f926840bfe1733b70cbca82c0ab",
      "content_id": 100,
      "content_session_id": "917a34072663f9c8beea3b45e8f129c5",
      "adblock_id" : 1101,
      "adblock_session_id" : "3fbc5f926840bfe1733b70cbca82c0ab",
      "start": "2019-03-13T12:00:00Z",
      "end": "2019-03-13T12:02:00Z"
    },
    {
      "campaign_id": 10,
      "campaign_content_id": 3,
      "campaign_session_id": "3fbc5f926840bfe1733b70cbca82c0ab",
      "content_id": 100,
      "content_session_id": "331c6883dd6010864b7ead130be77cd5",
      "start": "2019-03-13T12:02:00Z",
      "end": "2019-03-13T12:04:00Z"
    }
  ],
  "campaign_sessions": [
    {
      "id": "3fbc5f926840bfe1733b70cbca82c0ab",
      "campaign_id": 10,
      "status": "start",
      "ts": "2019-03-13T12:02:00Z",
      "adblock_id" : 1101,
      "adblock_session_id" : "3fbc5f926840bfe1733b70cbca82c0ab",
    }
  ],
  "adblock_sessions": [
    {
      "id": "3fbc5f926840bfe1733b70cbca82c0ab",
      "adblock_id": 1101,
      "status": "start",
      "ts": "2019-03-13T12:02:00Z"
    }
  ],
  "mac": [
    {
      "start": "2019-10-01T21:10:34.910+03:00",
      "end": "2019-10-01T21:20:04.637+03:00",
      "value": "00:00:5e:00:53:01",
      "vendor" : "awesome vendor"
    },
    {
      "start": "2019-10-01T21:10:34.910+03:00",
      "end": "2019-10-01T21:20:04.637+03:00",
      "value": "02-00-5e-10-00-00-00-01",
      "vendor": "apple"
    },
    {
      "start": "2019-10-01T21:10:34.910+03:00",
      "end": "2019-10-01T21:20:04.637+03:00",
      "value": "00-00-00-00-fe-80-00-00-00-00-00-00-02-00-5e-10-00-00-00-01"
    },
    {
      "start": "2019-10-01T21:10:34.910+03:00",
      "end": "2019-10-01T21:20:04.637+03:00",
      "value": "0000.5e00.5301"
    },
    {
      "start": "2019-10-01T21:10:34.910+03:00",
      "end": "2019-10-01T21:20:04.637+03:00",
      "value": "0200.5e10.0000.0001"
    },
    {
      "start": "2019-10-01T21:10:34.910+03:00",
      "end": "2019-10-01T21:20:04.637+03:00",
      "value": "0000.0000.fe80.0000.0000.0000.0200.5e10.0000.0001"
    }
  ]
}
```

### Описание полей

- `track.identity_type` - тип уникальности посетителя:
    - Тип может содержать одно из двух значений:
        - person - посчитался дескриптор лица
        - track - не самый достоверный идентификатор :) 
- `track.start` - время появленя персоны в зоне видимости камеры
- `track.end` - время ухода персоны из зоны видимости камеры
- `track.merge` - массив идентификаторов персон, которые являются одной и той же персоной, что и эта. На основе этих данных мы будем "схлопывать" разные персоны в одну
- `view.campaign_session_id` - идентификатор сессии показа рекламной кампании, в пределах которой был просмотр данного контента
- `view.content_session_id` - идентификатор сессии показа одного контента, в котором был совершен просмотр
- `shows.content_session_id` - идентификатор сессии показа одного контента

- `track.visitor.attributes` - приходит только если identity_type = person
- `track.visitor.attributes.emotions[*].value`- значение эмоции [**anger**, **fear**, **happiness**, **neutral**, **sadness**, **surprise**]
- `track.visitor.attributes.smile[*].time`- значение улыбки [**no**, **smiling**]
- `track.visitor.attributes.pitch[*].value`- значение pitch (от -180 до 180)
- `track.visitor.attributes.yaw[*].value`- значение yaw (от -180 до 180)
- `track.visitor.attributes.x[*].value`- значение x (от 0 до 100)
- `track.visitor.attributes.y[*].value`- значение y (от 0 до 100)
- `track.visitor.attributes.height[*].value`- значение height (от 0 до 100)
- `track.visitor.attributes.*[*].time`- время изменения (массив времени последовательный каждый tme > предыдущего)

Сохраняем посетителей
Сохрянаем просмотры контента по каждому посетителю


#### Сессии РК
Серверу нужно понимать, когда РК начала и закончила воспроизводиться. Для этого плееру необходимо отправить статус сессии и время. 

```json
{
  "id": "3fbc5f926840bfe1733b70cbca82c0ab",
  "campaign_id" : 10,
  "status" : "start",
  "ts" : "2019-03-13T12:02:00Z"
}
```

- `сampaign_session.id` - идентификатор сессии
- `сampaign_session.status` - статус сессии 
    - Статус может быть 2 типов:
        - start - Начало воспроизведения РК
        - end - Конец воспроизведения РК
- `сampaign_session.ts` - время события

Событие необходимо слать только в случае изменения статуса. 

##### Вопросы:
- Стоит ли слать только изменения, мб следует постоянно отправлять статус РК во время ее воспроизведения?
- Что делать, если устройство по какой-либо причине не пришлет статус о завершения запроса. Какой тайм-аут сессии?  




____


### Как схлопывать треки (не для плеера)
#### Встроенными средствами clickhouse

- Создать materialized view с агрегационной функцией. Но такой вариант не подойдет, т.к. все треки по одному визитору будут схлопываться в одну сессию, а нам нужно на несколько, чтобы между сессиями было как минимум три часа (настраиваемый параметр).
- Создать таблицу с движком AggregatingMergeTree или подобным, но у этого подхода такой же недостаток, как у materialized view - все треки схлопнуться в один.
- Схлопывать треки "на лету", т.е. во время select'a, как рассказано в этом видео https://www.youtube.com/watch?v=JJRQ0KhUovc. Но есть сомнения по использованию этого подхода, т.к. не факт, что можно схлопнуть сессии через лямбда-функции (хотя в теории возможность есть) и есть сомнения в производительности данного подхода, т.к. с ростом таблицы данных будет все больше и больше.
- 