Как я могу отслеживать номер записи по нескольким объектам json в Stack Overflow

У меня есть экспорт записей клиентов, которые нужно было разделить на несколько частей по 500 записей. Я получаю каждый кусок через запрос REST и сохраняю его на своем сервере:

public function createImportFile($json)
{
$filePath = storage_path().'/import/'.$this->getImportFileName($this->import->chunkNumber);
$importFile = fopen($filePath, 'w');
$array = json_decode($json);

fwrite($importFile, $json);
fclose($importFile);
return $filePath;

}

Затем, взяв все фрагменты, я импортирую все записи. Мне интересно, как лучше найти N-ную запись среди всех кусков?

В настоящее время я делю номер нужной записи на общее количество чанков, чтобы выяснить, в каком чанке будет находиться запись. Затем я получаю общее количество записей для предыдущих чанков и вычитаю это число из номера записи в получить позицию записи в куске.

while ($this->recordNumber <= $this->totalRecords) {
$item = $this->getRecord($this->recordNumber);
if (empty($item)) {
$this->recordNumber++;
continue;
}
$results = $this->translateItem($item);
$this->recordNumber++;
}
public function getRecord($recordNumber)
{
if ($this->import->isChunkedImport()) {
$chunkNumber = (integer) $this->returnChunkFromRecordNumber($recordNumber);
$countInPrevChunks = intval($this->returnRecordCountForPrevChunks($chunkNumber));
$chunkPosition = intval($this->getChunkPosition($recordNumber, $countInPrevChunks));
$jsonObj = $this->getJsonObjectForChunkNumer($chunkNumber);
return $jsonObj[$chunkPosition];
}
else {
$chunkPosition = $this->getChunkPosition($recordNumber, 0);
$filePath = storage_path().'/import/'.$this->getImportFileName();
return (array) json_decode(file_get_contents($filePath))[$chunkPosition];
}
}

private function &getJsonObjectForChunkNumer($chunkNumber)
{
if ($this->currentFileArray == null || ($chunkNumber != $this->lastChunkNumber)) {
$filePath = storage_path().'/import/'.$this->getImportFileName($chunkNumber);
$this->currentFileArray = json_decode(file_get_contents($filePath), true);
$this->lastChunkNumber = $chunkNumber;
}
return $this->currentFileArray;
}

public function getChunkCount()
{
$filePath = storage_path().'/import/'.$this->getImportFileName();
return count(json_decode(file_get_contents($filePath)));
}

public function returnChunkFromRecordNumber($recordNumber)
{

if ($recordNumber >= $this->getChunkCount()) {
if (is_int($recordNumber/$this->getChunkCount())) {
if (($recordNumber/$this->getChunkCount()) == 1) {
return intval(1);
}
return intval(($recordNumber/$this->getChunkCount())-1);
}
else {
return intval($recordNumber/$this->getChunkCount());
}
}
else {
return intval(0);
}
}

public function getChunkPosition($recordNumber, $countInPrevChunks)
{
$positionInChunk = $recordNumber - $countInPrevChunks;
if ($positionInChunk == 0) {
return $positionInChunk;
}
return $positionInChunk - 1;
}

public function returnRecordCountForPrevChunks($chunkNumber)
{
if ($chunkNumber == 0) {
return 0;
}
else {
return $this->getChunkCount() * $chunkNumber;

Я пытаюсь учесть, что первый ключ для чанков и записей в чанках равен 0, но мне все еще не хватает последней записи импорта. Также кажется, что я могу сделать это более сложным, чем нужно. Мне было интересно, есть ли у кого-нибудь совет или более простой способ взять N-ную пластинку. Я подумал о возможной нумерации записей по мере их ввода с помощью запроса REST, затем я смог найти Чанк, содержащий номер записи, в качестве ключа массива, а затем вернуть эту запись:

public function createImportFile($json)
{
$filePath = storage_path().'/import/'.$this->getImportFileName($this->import->chunkNumber);
$importFile = fopen($filePath, 'w');
if ($this->import->chunkNumber == 0 && $this->recordNumber == 0) $this->recordNumber = 1;
$array = json_decode($json);
$ordered_array = [];
foreach ($array as $record) {
$ordered_array[$this->recordNumber] = $record;
$this->recordNumber++;
}
fwrite($importFile, json_encode($ordered_array));
fclose($importFile);
return $filePath;
}

Но я не был уверен, что это лучший подход.

0

Решение

Имея много записей, вы можете использовать таблицу базы данных. MySQL легко обрабатывает десятки тысяч записей. Вам даже не нужно хранить целые записи. Возможно просто:

record_no | chunk_no | position_in_chunk
  • record_no: Основной ключ. Уникальный идентификатор для этой записи
  • chunk_no: Какой кусок содержит запись
  • position_in_chunk: Где в чанке находится запись

Положить UNIQUE(chunk_no, position_in_chunk) указатель на стол.

Затем, когда вы извлекаете записи, присваиваете им номер, формируете таблицу БД и сохраняете таблицу при записи записей на диск. В будущем, чтобы получить конкретную запись, вам понадобится только ее номер.

Если вы не хотите использовать базу данных, вы также можете сохранить эти данные в виде файла JSON, хотя производительность поиска будет страдать от необходимости каждый раз открывать и анализировать большой файл JSON.

1

Другие решения

Других решений пока нет …