Intereting Posts
PHP strtotime проблемы с минутами phpseclib / jsbn: шифрование с открытым ключом в PHP, дешифрование с помощью закрытого ключа в jsbn Как извлечь данные из сеанса в PHP? используйте http для запуска запроса на удаленном sql db как эффективно я могу использовать filter_var ($ email, FILTER_VALIDATE_EMAIL).? Как сделать PDF-файл с помощью PHP как динамически изменять элемент двух связанных полей CodeIgniter: как сделать выбор (Distinct Fieldname) MySQL Query Форма: позвольте пользователю выбрать свою страну (раскрывающийся список) и получить валюту (php) Как проверить, что наша электронная почта была прочитана в веб-почте с использованием PHP Получение «косвенной модификации перегруженного имущества не имеет никакого эффекта» Пакеты Composer, автозагрузка неклассифицированных файлов phpMyAdmin для GAE – аутентификация Найти min / max в двухмерном массиве Что мне нужно для кода для использования HTTPS?

Как правильно выполнить итерацию через большой файл json

Уважаемый форум Stackoverflow,

У меня есть 34-дюймовый json-файл с большим количеством данных. Я попытался импортировать в мой mongodb с помощью mongoimport –file file.json – но это не привело к тому, что файл слишком велик и выбросил ошибку системы памяти, которую вы знаете. Можно ли использовать PHP-код для итерации через файл с помощью курсора? У меня нет опыта в этом, кто-то сказал мне, что это будет возможно. Я хочу знать, как файл создается, но я не знаю, как его просмотреть. Из источника я мог бы получить массив примеров:

{ "_id": ObjectId("53b29644aafd413977b23b7e"), "summonerId": NumberLong(24570940), "region": "euw", "updatedAt": NumberLong(1404212804), "season": NumberLong(4), "stats": { "110": { "totalSessionsPlayed": NumberLong(3), "totalSessionsLost": NumberLong(2), "totalSessionsWon": NumberLong(1), "totalChampionKills": NumberLong(34), "totalDamageDealt": NumberLong(415051), "totalDamageTaken": NumberLong(63237), "mostChampionKillsPerSession": NumberLong(12), "totalMinionKills": NumberLong(538), "totalDoubleKills": NumberLong(5), "totalTripleKills": NumberLong(1), "totalDeathsPerSession": NumberLong(18), "totalGoldEarned": NumberLong(40977), "totalTurretsKilled": NumberLong(6), "totalPhysicalDamageDealt": NumberLong(381668), "totalMagicDamageDealt": NumberLong(31340), "totalAssists": NumberLong(25), "maxChampionsKilled": NumberLong(12), "maxNumDeaths": NumberLong(10) } } } 

Статистика полей содержит больше массивов, 110 – пример. Как я могу перебирать этот файл большого размера или как его импортировать в мой mongodb? Например; Я хочу повторить summonerid, championid (в этом случае 110), totalSessionsPlayed. Он должен релонировать столько, сколько ему нужно, пока theres не останется у кого-то, кто захочет этого конкретного summonerid.

Снова … У summonerID есть список чемпионов, которые он играл в своей игровой карьере. Чемпионы имеют в виду (в этом примере) 110. Каждый вызов summonerid может содержать несколько чемпионов, и я хочу иметь всех чемпионов, сколько раз чемпион играл (totalsessionplayed) summonerid.

Вы хотите использовать потоковой парсер. Они только вытягивают небольшие части вашего файла в память за раз.

Они входят в пару разных вкусов: SAX-подобные синтаксические парсеры и вытягивают парсеры. Модели XML-читателей: SAX и XML-анализатор дают общий обзор разницы.


Push Parser

Это быстрый пример с использованием salsify / json-streaming-parser .

Когда он просматривает файл, мы будем отслеживать имя summonerId , championId и state. Все зависит от событий – вы не получаете случайный доступ с последовательным парсером, поэтому вам нужно самому отслеживать все. Каждый раз, когда totalSessionsPlayed , он будет вызывать summonerId , championId и totalSessionsPlayed .


data.json

Это дробный файл json для демонстрации.

 [ { "_id": "53b29644aafd413977b23b7e", "summonerId": 24570940, "region": "euw", "stats": { "110": { "totalSessionsPlayed": 3, "totalSessionsLost": 2, "totalSessionsWon": 1 }, "112": { "totalSessionsPlayed": 45, "totalSessionsLost": 2, "totalSessionsWon": 1 } } }, { "_id": "asdfasdfasdf", "summonerId": 555555, "region": "euw", "stats": { "42": { "totalSessionsPlayed": 65, "totalSessionsLost": 2, "totalSessionsWon": 1 }, "88": { "totalSessionsPlayed": 99, "totalSessionsLost": 2, "totalSessionsWon": 1 } } } ] 

Пример:

 class ListMatchUps extends JsonStreamingParser\Listener\IdleListener { private $key; private $summonerId; private $championId; private $inStats; public function start_document() { $this->key = null; $this->summonerId = null; $this->championId = null; $this->inStats = false; } public function start_object() { if ($this->key === 'stats') { $this->inStats = true; } else if ($this->inStats) { $this->championId = $this->key; } } public function end_object() { if ($this->championId !== null) { $this->championId = null; } else if ($this->inStats) { $this->inStats = false; } else { $this->summonerId = null; } } public function key($key) { $this->key = $key; } public function value($value) { switch ($this->key) { case 'summonerId': $this->summonerId = $value; break; case 'totalSessionsPlayed': echo "{$this->summonerId},{$this->championId},$value\n"; break; } } } $stream = fopen('data.json', 'r'); $listener = new ListMatchUps(); try { $parser = new JsonStreamingParser_Parser($stream, $listener); $parser->parse(); } catch (Exception $e) { fclose($stream); throw $e; } 

Вывод:

 24570940,110,3 24570940,112,45 555555,42,65 555555,88,99 

Pull Parser

Это используется парсер, который я недавно написал, pcrov / jsonreader (требуется PHP 7.)

То же data.json, что и выше.

Пример:

 use pcrov\JsonReader\JsonReader; $reader = new JsonReader(); $reader->open("data.json"); while($reader->read("summonerId")) { $summonerId = $reader->value(); $reader->next("stats"); foreach($reader->value() as $championId => $stats) { echo "$summonerId, $championId, {$stats['totalSessionsPlayed']}\n"; } } $reader->close(); 

Вывод:

 24570940, 110, 3 24570940, 112, 45 555555, 42, 65 555555, 88, 99