Github GraphQL API v.4.0 неправильно работает курсор - PullRequest
3 голосов
/ 07 октября 2019

Я пытаюсь получить список всех репозиториев из Github, чтобы провести некоторый анализ. Я начал свою работу с API v3.0, который является Restful, а затем, когда мне понадобилась дополнительная информация, такая как подсчет звезд, перешел с v3.0 на v4.0, который предоставляется как GraphQL. Теперь я делаю запрос на 100 записей каждый раз и делаю это рекурсивно, чтобы иметь возможность получить все записи.

Проблема в работе с нумерацией страниц. Для работы разбивки на страницы мне нужно получить endCursor каждого запроса, а затем в следующем запросе я должен заполнить свойство после этого значением. Теперь проблема в том, что данные не разбиты на страницы должным образом. Например:

  1. Запрос первой страницы (без курсора) приводит к различным записям.
  2. Запрос страницы с одним и тем же курсором несколько раз, также приводит к получению разных результатов.
  3. И если просто не проверять это и пытаться извлекать одну за другой, каждые 100 записей имеют много дубликатов с предыдущими запросами, что означает, что разбиение на страницы не работает правильно.

Запрос, которым я являюсьотправка (в приложении nodejs) выглядит следующим образом:

{
  search(query: "is:public", type: REPOSITORY, first: 100, after: "Y3Vyc29yOjEwMA==") {
    repositoryCount
    userCount
    wikiCount
    pageInfo {
      startCursor
      endCursor
      hasNextPage
      hasPreviousPage
    }
    edges {
      node {
        ... on Repository {
          databaseId
          id
          name
          description
          forkCount
          isFork
          issues {
            totalCount
          }
          labels (first: 100) {
            nodes {
              name
            }
          }
          languages (first: 100) {
            nodes {
              name
            }
          }
          licenseInfo {
            name
          }
          nameWithOwner
          primaryLanguage {
            name
          }
          pullRequests {
            totalCount
          }
          watchers {
            totalCount
          }
          stargazers {
            totalCount
          }
        }
      }
    }
  }
}

, как я уже говорил, в первый раз я удаляю параметр after из входных данных поиска, а затем использую endCursor предыдущего запроса в качестве параметра afterследующего.

Мне не хватает понимания цели курсора и его использования, или это ошибка (предназначенная / непреднамеренная) самого Github?

1 Ответ

3 голосов
/ 09 октября 2019

К счастью, я нашел способ, который работает на данный момент. И большое спасибо @Daniel Rearden за его очень полезный совет. Я протестировал множество строк запроса и обнаружил, что, если я запрашиваю конкретную дату создания, тогда данные сортируются в соответствии с этим полем и в моих тестах, теперь порядок остается неизменным, и курсор будет иметь значение.

Запрос теперь такой:

{
  search(query: "created:2008-02-08 is:public", type: REPOSITORY, first: 100) {
    repositoryCount
    userCount
    wikiCount
    pageInfo {
      startCursor
      endCursor
      hasNextPage
      hasPreviousPage
    }
    edges {
      node {
        ... on Repository {
          databaseId
          id
          name
          description
          forkCount
          isFork
          issues {
            totalCount
          }
          labels (first: 100) {
            nodes {
              name
            }
          }
          languages (first: 100) {
            nodes {
              name
            }
          }
          licenseInfo {
            name
          }
          nameWithOwner
          primaryLanguage {
            name
          }
          pullRequests {
            totalCount
          }
          watchers {
            totalCount
          }
          stargazers {
            totalCount
          }
          createdAt
          updatedAt
          diskUsage
        }
      }
    }
  }
}

Теперь единственное, о чем я должен подумать, - это прокрутить несколько дней и делать этот запрос много раз каждый день, пока pageInfo.hasNextPage не станет правдой.

К настоящему времени я не проверял это все ~ 4000 дней и, возможно, я не могу проверить, что выбранный результат - это все данные, которые существуют в их БД, но, похоже, это лучшее решение.

...