Забираем звонки из Webitel

Довольно часто наши клиенты сталкиваются с необходимостью выгрузить информацию о звонках из раздела Call Detail Record к себе. Как вы уже знаете (даже если взять во внимание предыдущую запись в этом блоге, а именно Липкость звонка), вся историческая статистика хранится в базе elasticsearch. В документации вы так же могли увидеть пример получения данных с помощью нашего REST API. Но, что если звонков несколько сотен? Или несколько тысяч? Как правильно получить такой объем данных? Сегодня я расскажу как работать с большими объемами данных.

Scroll

Для получения большого количества данных, в elasticsearch предусмотрен функционал scroll, который мы повторили и в нашем REST API. Рассмотрим на примере:

{
    "scroll" : "5m",
    "limit": 1000,
    "sort": {
        "created_time": {
            "order": "desc",
            "unmapped_type": "boolean"
        }
    },
    "index": "cdr-a",
    "query": "*",
    "columns": [
        "created_time",
        "uuid",
        "direction",
        "duration"
    ],
    "filter": [
        {
            "bool": {
                "must": [
                    {
                        "range": {
                            "created_time": {
                                "gte": "now/w",
                                "lte": "now"
                            }
                        }
                    }
                ]
            }
        }
    ]
}

В тело нашего запроса мы добавили 2 новых параметра:

  • scroll – как долго на сервере держать результат запроса
  • limit – какими порциями возвращать результат запроса

Дальше, выполняем первый запрос с указанным телом на REST API, для простоты я использую консольную утилиту cURL:

curl -s -L -XPOST \
    -H 'Content-Type: application/json' \
    -H 'X-Access-Token: ciOiJIUzI1NiJ9.jEyM2UxNThjLWVkNzMtNDAwi'\
    "https://pre.webitel.com/engine/api/v2/cdr/text" -d@webitel_scroll_request.json

Вместе с результатом, который не будет превышать заданного в limit значения, мы получим _scroll_id.

Теперь все последующие запросы мы выполняем уже с scrollId в теле запроса. Пример:

curl -s -L -XPOST \
    -H 'Content-Type: application/json' \
    -H 'X-Access-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6I9.IjKpitL05OLjUPeUQyd4E'\
    "https://pre.webitel.com/engine/api/v2/cdr/text/scroll" -d '
        {
            "scroll": "5m",
            "scrollId": 'МНОГО_БУКВ_ПОЛУЧЕННОГО_ИД'
        }'

Повторяем запрос, пока не заберем все данные с сервера.

Бонус

В качестве бонуса, подготовил небольшой bash скрипт, который с помощью cURL и jq поможет вам выкачать необходимые данные и сохранить в CSV файл:


#!/bin/bash
rm cdr.csv

tmpfile=$(mktemp /tmp/scroll.XXXXXX)
scroll_id=$(curl -s -L -XPOST \
    -H 'Content-Type: application/json' \
    -H 'X-Access-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEyM2UxNThjLWVkNzMtNDAzOC1hOWExLTA5Y2MxZjk4ZDJmYSIsImV4cCI6MTU0OTQ5MDQwMDAwMCwiZCI6IndlYml0ZWwuZHJydXBpYWguY29tIiwidCI6ImRvbWFpbiIsInYiOjJ9.IjK6q1ra6um1ZJ0_gJImkNcZUpitL05OLjUPeUQyd4E'\
    "https://pre.webitel.com/engine/api/v2/cdr/text" -d@webitel_scroll_request.json | tee >(jq -r '.hits.hits[].fields | [.created_time[], .uuid[], .direction[], .duration[]] | @csv' >>cdr.csv) >(jq '.hits.hits | length' >${tmpfile}) | jq ._scroll_id)
size=$(cat ${tmpfile})
total=$size

while [ $size -ge 1000 ]
do
    size=$(curl -s -L -XPOST \
        -H 'Content-Type: application/json' \
        -H 'X-Access-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEyM2UxNThjLWVkNzMtNDAzOC1hOWExLTA5Y2MxZjk4ZDJmYSIsImV4cCI6MTU0OTQ5MDQwMDAwMCwiZCI6IndlYml0ZWwuZHJydXBpYWguY29tIiwidCI6ImRvbWFpbiIsInYiOjJ9.IjK6q1ra6um1ZJ0_gJImkNcZUpitL05OLjUPeUQyd4E'\
        "https://pre.webitel.com/engine/api/v2/cdr/text/scroll" -d '
        {
            "scroll": "5m",
            "scrollId": '${scroll_id}'
        }' | tee >(jq -r '.hits.hits[].fields | [.created_time[], .uuid[], .direction[], .duration[]] | @csv' >>cdr.csv) | jq '.hits.hits | length')
    echo $size
    total=$(( $total   $size ))
done

echo "$total - done"

rm $tmpfile
exit 0

Тело запроса должно находится в файле webitel_scroll_request.json в возле данного скрипта.

Удачи с запросами!

Leave a Reply

Your email address will not be published. Required fields are marked *