پر کردن مقادیر از دست رفته از درخواست های تاریخ

نیک میهایلوسکی، تیم Google Analytics API – اکتبر 2009

این مقاله نحوه شناسایی و پر کردن مقادیر سری زمانی از دست رفته در داده‌های بازگردانده شده از Google Analytics Data Export API را مورد بحث قرار می‌دهد.


قبل از اینکه شروع کنی

این مقاله فرض می‌کند که می‌دانید Google Analytics Data Export API چگونه کار می‌کند. کد نمونه در جاوا است اما می توانید از مفاهیم به زبان انتخابی خود استفاده کنید. کد این مقاله به صورت متن باز ارائه شده و از هاست پروژه قابل دانلود است.

پس از مطالعه این مقاله خواهید آموخت:

  • چگونه Google Analytics Data Export API با ابعاد تاریخ برخورد می کند.
  • چگونه پرس و جوهای خود را برای گروه بندی نتایج و شناسایی تاریخ های گمشده ساختار دهید.
  • نحوه پر کردن مقادیر از دست رفته با استفاده از جاوا

معرفی

مقایسه داده ها در یک دوره زمانی زمینه را فراهم می کند. به عنوان مثال، بیان اینکه یک وب سایت یک میلیون دلار درآمد ایجاد کرده است، معنای زیادی ندارد. اما بیان اینکه یک وب‌سایت درآمد را 10 برابر در سه ماهه یا سالیانه افزایش داده است واقعاً چشمگیر است. با Google Analytics API، ترسیم داده ها در طول زمان با استفاده از ابعاد ga:date ، ga:day و ga:month آسان است.

اگر درخواست شما فقط از یک بعد تاریخ استفاده می‌کند، اگر روزها در محدوده تاریخ داده‌های صفر را جمع‌آوری کرده باشند، API Google Analytics تاریخ‌ها و مقادیر 0 را برای معیارها تکمیل می‌کند.

ga:تاریخ ga: جلسات
01/03/2010 101
02/03/2010 0
03/03/2010 69

با این حال، اگر تاریخ را همراه با ابعاد دیگر جستجو کنید، مشکل می شود. اگر یکی از تاریخ‌ها داده‌ای نداشته باشد، API ورودی برای آن تاریخ برنمی‌گرداند . فقط به تاریخ موجود بعدی که حاوی داده است می‌پرد.

ga: کلمه کلیدی ga:تاریخ ga: جلسات
صندلی 01/03/2010 55
صندلی 03/03/2010 48

در حالت ایده‌آل، تحلیلگران می‌خواهند تاریخ‌های گمشده برای یک کلمه کلیدی خاص را مانند مثال اول بالا پر کنند.

این مقاله برخی از بهترین روش‌ها را برای پرکردن داده‌ها به طور عملی توضیح می‌دهد.

زمینه

بیایید ابتدا بررسی کنیم که چرا این مشکل وجود دارد. 2 دلیل وجود دارد.

  1. Google Analytics فقط داده های جمع آوری شده را پردازش می کند. اگر کسی در یک روز خاص به سایتی نیامد، هیچ داده ای برای پردازش وجود ندارد، بنابراین هیچ داده ای برگردانده نمی شود.
  2. تعیین اینکه چه تعداد ابعاد اضافی و چه مقادیری باید برای تاریخ هایی استفاده شود که داده ای ندارند بسیار دشوار است.

بنابراین به جای تلاش برای تعریف یک فرآیند برای کنترل همه آنها، API گوگل آنالیتیکس پر کردن داده‌ها را برای پرسش‌هایی که دارای ابعاد متعدد هستند به توسعه‌دهنده واگذار می‌کند. خوش به حالت :)

نمای کلی برنامه

در اینجا مراحل تکمیل داده ها در نمودار بالا آمده است.

  1. پرس و جو را اصلاح کنید تا مطمئن شوید ابعاد به صورت فرصت طلبانه مرتب شده اند.
  2. تاریخ های مورد انتظار را از محدوده تاریخ تعیین کنید.
  3. تاریخ‌های گمشده را تکرار و پر کنید.
  4. مقادیر باقیمانده را پر کنید.

پرس و جو را اصلاح کنید

برای تکمیل تاریخ‌ها، باید مطمئن شویم که داده‌های بازگردانده شده از API در قالبی هستند که تشخیص عدم وجود تاریخ را آسان می‌کند. در اینجا یک پرس و جو مثال برای بازیابی ga:keyword و ga:date برای 5 روز اول ماه مارس آمده است:

DataQuery dataQuery = new DataQuery(new URL(BASE_URL));
dataQuery.setIds(TABLE_ID);
dataQuery.setStartDate("2010-03-01");
dataQuery.setEndDate("2010-03-05");
dataQuery.setDimensions("ga:keyword,ga:date");
dataQuery.setMetrics("ga:entrances");

هنگامی که پرس و جو به API ارسال می شود، نتایج حاوی لیستی از اشیاء DataEntry خواهد بود. هر شی ورودی یک ردیف از داده ها را نشان می دهد و شامل نام ها و مقادیر برای ابعاد/متریک ها است. از آنجایی که هیچ پارامتر مرتب سازی استفاده نشده است، نتایج به ترتیب دلخواه برگردانده می شوند.

ga: کلمه کلیدی ga:تاریخ ga:ورودی ها
صندلی 04/03/2010 14
صندلی 01/03/2010 23
جدول 04/03/2010 18
جدول 02/03/2010 24
صندلی 03/03/2010 13

برای سهولت در تشخیص تاریخ های مفقود، ابتدا باید همه ابعاد را با هم گروه بندی کنیم. این را می توان با تنظیم پارامتر مرتب سازی پرس و جو با ابعاد استفاده شده در پرس و جو اصلی انجام داد.

dataQuery.setSort("ga:keyword,ga:date");

افزودن پارامتر مرتب سازی باعث می شود API نتایج را به ترتیب دلخواه برگرداند.

ga: کلمه کلیدی ga:تاریخ ga:ورودی ها
صندلی 01/03/2010 23
صندلی 03/03/2010 13
صندلی 04/03/2010 14
جدول 02/03/2010 24
جدول 04/03/2010 18

مرحله دوم این است که مطمئن شوید برای هر بعد، تمام تاریخ ها به ترتیب صعودی برگردانده می شوند. در حالی که Google Analytics API تعدادی از ابعاد تاریخ را ارائه می دهد، فقط ga:date می توان به طور دقیق در مرزهای تاریخ (یعنی روز، ماه، سال) مرتب کرد. بنابراین اگر می‌خواهید تاریخ‌ها را تکمیل کنید، مطمئن شوید که درخواست شما از بعد ga:date در پارامترهای ابعاد و مرتب‌سازی استفاده می‌کند.

هنگامی که پرس و جو مرتب شده اجرا شد، همه صفحات فرود یکسان در کنار یکدیگر برگردانده می شوند و تاریخ ها به ترتیب ترتیب داده می شوند. فهرست تاریخ‌های یک صفحه فرود را می‌توان به‌عنوان یک سری زمانی در نظر گرفت و چون مرتب هستند، شناسایی تاریخ‌های گمشده بسیار آسان‌تر است.

تاریخ های مورد انتظار را تعیین کنید

برای شناسایی تاریخ‌های گمشده، باید تاریخ‌های واقعی بازگشتی از API را با تاریخ‌های مورد انتظار در هر سری زمانی مقایسه کنیم. ما می توانیم بفهمیم که چه چیزی مورد انتظار است:

  1. تعیین تاریخ شروع مورد انتظار از کوئری API.
  2. شمارش تعداد روزهای مورد انتظار در محدوده تاریخ درخواست.

هر دو مقدار را می توان با هم برای تعیین هر تاریخ مورد انتظار با افزایش تاریخ شروع 1 برای هر روز در محدوده تاریخ استفاده کرد.

تعیین تاریخ شروع مورد انتظار

ما می توانیم از پارامتر پرس و جو start-date به عنوان تاریخ شروع مورد انتظار سری استفاده کنیم. از آنجایی که قالب تاریخ بازگردانده شده در پاسخ API yyyyMMdd با فرمت پارامتر پرس و جو yyyy-MM-dd متفاوت است، ابتدا باید قالب تاریخ را قبل از استفاده از آن تبدیل کنیم.

متد setExpectedStartDate فرمت تاریخ ها را تبدیل می کند.

  private static SimpleDateFormat queryDateFormat = new SimpleDateFormat("yyyy-MM-dd");
  private static SimpleDateFormat resultDateFormat = new SimpleDateFormat("yyyyMMdd");

  public void setExpectedStartDate(String startDate) {
    try {
      calendar.setTime(queryDateFormat.parse(startDate));
      expectedStartDate = resultDateFormat.format(calendar.getTime());
    } catch (ParseException e) {
      handleException(e);
    }
  }

شمارش تعداد روزهای مورد انتظار

برای به دست آوردن تعداد روزهای در محدوده تاریخ، برنامه تاریخ شروع و پایان را در اشیاء Date جاوا تجزیه می کند. سپس از یک شی Calendar برای تعیین زمان بین هر دو تاریخ استفاده می کند. یک روز به تفاوت تاریخ اضافه می شود تا شمارش شامل شود.

  private static final long millisInDay = 24 * 60 * 60 * 1000;

  public void setNumberOfDays(DataQuery dataQuery) {
    long startDay = 0;
    long endDay = 0;

    try {
      calendar.setTime(queryDateFormat.parse(dataQuery.getStartDate()));
      startDay = calendar.getTimeInMillis() / millisInDay;

      calendar.setTime(queryDateFormat.parse(dataQuery.getEndDate()));
      endDay = calendar.getTimeInMillis() / millisInDay;
    } catch (ParseException e) {
      handleException(e);
    }

    numberOfDays = (int) (endDay - startDay + 1);
  }

اکنون ما تمام داده‌های مورد نیاز خود را داریم تا بفهمیم کدام تاریخ‌ها گم شده‌اند.

هر سری زمانی را در نتایج مشخص کنید

هنگامی که پرس و جو اجرا شد، برنامه از طریق هر شی DataEntry در پاسخ API عبور می کند. از آنجایی که پرس و جو در ابتدا مرتب شده بود، پاسخ یک سری زمانی جزئی برای هر کلمه کلیدی خواهد داشت. بنابراین ما باید شروع هر سری زمانی را پیدا کنیم، سپس هر تاریخ را مرور کنیم و داده های گمشده را که توسط API برگردانده نشده است را پر کنیم.

این برنامه از متغیرهای dimensionValue و tmpDimensionValue برای تشخیص شروع هر سری استفاده می کند.

در اینجا کل کد برای رسیدگی به پاسخ است. پر کردن داده های از دست رفته در زیر بحث شده است.

public void printBackfilledResults(DataFeed dataFeed) {
  String expectedDate = "";
  String dimensionValue = "";
  List<Integer> row = null;

  for (DataEntry entry : dataFeed.getEntries()) {
    String tmpDimValue = entry.getDimensions().get(0).getValue();

    // Detect beginning of a series.
    if (!tmpDimValue.equals(dimensionValue)) {
      if (row != null) {
        forwardFillRow(row);
        printRow(dimensionValue, row);
      }

      // Create a new row.
      row = new ArrayList<Integer>(numberOfDays);
      dimensionValue = tmpDimValue;
      expectedDate = expectedStartDate;
    }

    // Backfill row.
    String foundDate = entry.getDimension("ga:date").getValue();
    if (!foundDate.equals(expectedDate)) {
      backFillRow(expectedDate, foundDate, row);
    }

    // Handle the data.
    Metric metric = entry.getMetrics().get(0);
    row.add(new Integer(metric.getValue()));
    expectedDate = getNextDate(foundDate);
  }

  // Handle the last row.
  if (row != null) {
    forwardFillRow(row);
    printRow(dimensionValue, row);
  }
}

تاریخ های گمشده را پر کنید

برای هر ورودی در یک سری، برنامه مقادیر متریک (ورودی ها) را در یک ArrayList به نام row ذخیره می کند. هنگامی که یک سری زمانی جدید شناسایی می شود، یک ردیف جدید ایجاد می شود و تاریخ مورد انتظار روی تاریخ شروع مورد انتظار تنظیم می شود.

سپس برای هر ورودی، برنامه بررسی می کند که آیا مقدار تاریخ در ورودی برابر با تاریخ مورد انتظار است یا خیر. اگر برابر باشند، متریک ورودی به ردیف اضافه می شود. در غیر این صورت، برنامه تاریخ های گم شده ای را شناسایی کرده است که باید تکمیل شوند.

متد backfillRow داده‌های پشت پر کردن را مدیریت می‌کند. تاریخ های مورد انتظار و یافت شده و همچنین ردیف فعلی را به عنوان پارامتر می پذیرد. سپس تعداد روزهای بین دو تاریخ (غیرشامل) را تعیین می کند و 0های زیادی را به ردیف اضافه می کند.

  public void backFillRow(String startDate, String endDate, List<Integer> row) {
    long d1 = 0;
    long d2 = 0;

    try {
      calendar.setTime(resultDateFormat.parse(startDate));
      d1 = calendar.getTimeInMillis() / millisInDay;

      calendar.setTime(resultDateFormat.parse(endDate));
      d2 = calendar.getTimeInMillis() / millisInDay;

    } catch (ParseException e) {
      handleException(e);
    }

    long differenceInDays = d2 - d1;
    if (differenceInDays > 0) {
      for (int i = 0; i < differenceInDays; i++) {
        row.add(0);
      }
    }
  }

هنگامی که روش انجام شد، ردیف با داده ها پر شده است و داده های فعلی را می توان اضافه کرد. سپس تاریخ مورد انتظار با استفاده از روش getNextDate به یک روز پس از تاریخ پیدا شده افزایش می یابد.

public String getNextDate(String initialDate) {
  try {
    calendar.setTime(resultDateFormat.parse(initialDate));
    calendar.add(Calendar.DATE, 1);
    return resultDateFormat.format(calendar.getTime());

  } catch (ParseException e) {
    handleException(e);
  }
  return "";
}

هر مقدار باقیمانده را پر کنید

هنگامی که داده‌های سری در یک row پردازش شدند، باید بررسی کنیم که تاریخ‌های گمشده دیگری در پایان سری وجود نداشته باشد.

متد forwardFillRow به سادگی تفاوت بین تعداد روزهای پرس و جو اصلی را با اندازه فعلی سطر محاسبه می کند و 0های زیادی را به انتهای سطر اضافه می کند.

public void forwardFillRow(List<Integer> row) {
  int remainingElements = numberOfDays - row.size();
  if (remainingElements > 0) {
    for (int i = 0; i < remainingElements; i++) {
      row.add(0);
    }
  }
}

در این مرحله، برنامه هر مقدار از دست رفته در سری زمانی را پر کرده است. اکنون که همه داده ها را در اختیار داریم، برنامه مقادیر ابعاد و متریک را به صورت لیست جدا شده با کاما چاپ می کند.

نتیجه

با استفاده از این نمونه، می توانید به راحتی داده ها را در تاریخ هایی که توسط API برگردانده نشده اند، تکمیل کنید. همانطور که در بالا ذکر شد، این راه حل می تواند با هر زبان برنامه نویسی سازگار شود. توسعه‌دهندگان حتی می‌توانند این تکنیک‌ها را تطبیق دهند و از آن‌ها برای مدیریت ابعاد و معیارهای متعدد استفاده کنند. اکنون حتی ساده‌تر از همیشه شروع به انجام تجزیه و تحلیل پیشرفته در سری‌های زمان بازگشتی توسط Google Analytics API است.