2017-09-01 2 views
0

Ich habe einen Export von Kundenaufzeichnungen, die über mehrere Brocken von 500 Datensätzen aufgeteilt werden mussten. Ich packe jeden Brocken durch eine REST Anfrage, speichern Sie es auf meinem Server:Wie kann ich die Datensatznummer über mehrere JSON-Objekte in PHP verfolgen

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; 

} 

Dann, nach all den Brocken packte ich alle Datensätze importieren. Ich frage mich, was der beste Weg wäre, den N-ten Rekord unter all den Brocken zu finden?

Momentan teile ich die gesuchte Datensatznummer durch die Gesamtzahl der Chunks, um herauszufinden, in welchem ​​Chunk der Datensatz enthalten ist. Dann erhalte ich die Gesamtdatensätze für die vorherigen Chunks und subtrahiere diese Zahl von die Datensatznummer, um die Position des Datensatzes im Chunk zu erhalten.

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; 

Ich versuche, für den ersten Schlüssel für beiden Chunks zu berücksichtigen und Aufzeichnungen in dem Chunks 0, aber ich bin immer noch den letzten Datensatz des Imports fehle. Es scheint auch, als würde ich das komplizierter machen, als es sein muss. Ich habe mich gefragt, ob jemand einen Rat oder eine einfachere Möglichkeit hatte, den N-ten Rekord zu ergattern. Ich dachte daran, möglicherweise nur die Datensätze Nummerierung, wie ich sie mit der REST-Anfrage bringe, dann könnte ich die Chunk enthält die Datensatznummer als Array Schlüssel finden und dann diesen Datensatz zurück:

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; 
} 

Aber ich war nicht sicher, ob das der beste Ansatz war.

Antwort

1

Mit vielen Datensätzen könnten Sie eine Datenbanktabelle verwenden. MySQL würde problemlos Zehntausende von Datensätzen verarbeiten. Sie müssten nicht einmal die ganzen Aufzeichnungen speichern. Vielleicht gerade:

record_no | chunk_no | position_in_chunk 
  • record_no: Primärschlüssel. Eindeutige Kennung für diesen Datensatz
  • chunk_no: Welche Brocken des Datensatz
  • position_in_chunk enthalten: Wo in den Brocken der Datensatz

Setzen Sie einen UNIQUE(chunk_no, position_in_chunk) Index auf dem Tisch befindet.

Wenn Sie Datensätze extrahieren, ordnen Sie ihnen eine Nummer zu, erstellen Sie die DB-Tabelle und speichern Sie die Tabelle, während Sie Datensätze auf die Festplatte schreiben. Um in Zukunft einen bestimmten Datensatz zu erhalten, benötigen Sie lediglich die Nummer.

Wenn Sie keine Datenbank verwenden möchten, können Sie diese Daten auch als JSON-Datei speichern. Allerdings leidet die Abrufleistung darunter, dass Sie jedes Mal eine große JSON-Datei öffnen und analysieren müssen.

Verwandte Themen