Ankündigung

Einklappen
Keine Ankündigung bisher.

Extremen JSON Response verarbeiten, ohne memory exhaust

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Extremen JSON Response verarbeiten, ohne memory exhaust

    Hallo,

    für eine WordPress-Seite würde ich gerne alle Schauspieler, die es über die TMDB-API gibt als Beiträge speichern. Um überhaupt an alle Einträge zu kommen, kann man einen täglichen Export aller IDs der Personen bekommen und mit den IDs dann jeweils die Details der Personen abrufen. So schön so gut. Leider sind es etwas über 2 Millionen IDs und wenn ich mir die Datei auslesen lasse und dann via foreach über die API jage reicht das Memory-Limit nicht aus. Ein setzen auf -1 des Limits kommt nicht in Frage, würde es mir zweifelsohne den Server killen.

    Die Datei splitten und in mehreren Anläufen iterieren wäre eine Idee, aber bei der schieren Masse an Daten wären das so viele einzelne Dateien, die nicht zu bewältigen wären.

    Hier mal mein Aufbau:
    (Die Liste mit den Person IDs ist nicht wirklich eine JSON, sondern beinhaltet JSON-Strings in Zeilen gespeichert)

    PHP-Code:
    $tmdb_url 'https://api.themoviedb.org/3/person/';
    $tmdb_api_key 'xxxxxxxxxxxxxxxxxxxxxxx';

    // Öffne die Liste mit JSON Content und zeile für zeile lesen
    $fileData = function() {
    $json_file get_template_directory() . '/person_ids_09_17_2021.json';
    $file fopen($json_file'r');
    if (!
    $file)
    die(
    'file does not exist or cannot be opened - ' var_dump($json_file));
    while ((
    $line fgets($file)) !== false) {
    yield 
    $line;
    }
    fclose($file);
    };

    // Jede Zeile JSON in einem Array kombinierenm
    $lines;
    foreach(
    $fileData() as $line) {
    $lines[] = json_decode($line);
    }

    // Die einzelnen Zeilen iterieren und mit der ID in jedem Durchgang die Details holen und alles in einem, Array speichern
    foreach($lines as $line) {
    $tmdb_id $line->id;
    $url $tmdb_url $tmdb_id '?api_key=' $tmdb_api_key '&language=de-DE';
    $request wp_remote_get$url );
    $body wp_remote_retrieve_body$request );
    $data json_decode($body);

    Mit $data will ich dann weiter arbeiten, allerdings erhalte ich im Vorfeld einen memory exhaust. Welche Möglichkeiten gibt es, diese Abfrage möglich zu machen ohne das memory limit derart zu strapazieren? Ich hab schon versucht, irgendwie um die Arrays herum zu kommen, aber bisher kein Erfolg

    Vielen Dank!

  • #2
    Wozu willst du 2 über 2 Millionen Beiträge in einem Array speichern? Was oder wer soll denn damit was anfangen können?
    Pre-Coffee-Posts sind mit Vorsicht zu geniessen!

    Kommentar


    • #3
      https://github.com/halaxa/json-machine

      Kommentar


      • #4
        Zitat von Thallius Beitrag anzeigen
        Wozu willst du 2 über 2 Millionen Beiträge in einem Array speichern? Was oder wer soll denn damit was anfangen können?
        Will ich ja nicht, allerdings fehlen mir die Alternativen um die Daten zu verarbeiten und in die WordPress Datenbank zu speichern. Das warum steht ja im Eingangspost, gelle

        Kommentar


        • #5
          Das Projekt kannte ich gar nicht. Tatsächlich lässt sich hiermit der große JSON Response verarbeiten. Vielen Dank!

          Kommentar


          • #6
            Durch yield füllst du $fileData bereits memory friendly. Dein Fehler ist, dass du danach ein neues $lines Array definierst. Du hättest stattdessen einfach ein foreach ($fileData... nutzen sollen.

            Ansonsten ist aber eh die Frage, ob du nicht einfach mit nur einer Schleife arbeitest.

            Außerdem solltest du die externe Datei nicht in den RAM laden, sondern herunterladen und die Datei dann weiter verarbeiten.
            meine PHP Scripte

            Kommentar


            • #7
              Zitat von hondatuner Beitrag anzeigen
              Durch yield füllst du $fileData bereits memory friendly. Dein Fehler ist, dass du danach ein neues $lines Array definierst. Du hättest stattdessen einfach ein foreach ($fileData... nutzen sollen.

              Ansonsten ist aber eh die Frage, ob du nicht einfach mit nur einer Schleife arbeitest.

              Außerdem solltest du die externe Datei nicht in den RAM laden, sondern herunterladen und die Datei dann weiter verarbeiten.
              Hey, ich habe deine Antwort leider erst jetzt gesehen. Also prinzipiell hast du recht, leider ist das Problem das jede einzelne Zeile ein json-String ist den es zu decoden gilt. Und alleine das frisst ja den Speicher schon auf. Mit der Datei hast du recht, die habe ich ja aber auch auf den Server geladen im Vorfeld. Die Funktion vorweg ist von WordPress und zeigt auf den Ordner, wo die Datei liegt.

              Kommentar


              • #8
                Zitat von hondatuner Beitrag anzeigen
                Außerdem solltest du die externe Datei nicht in den RAM laden, sondern herunterladen und die Datei dann weiter verarbeiten.
                Ob man die Daten zuerst herunterlädt oder direkt verarbeitet macht keinen Unterschied.

                Kommentar

                Lädt...
                X