Kombinieren Sie zwei aus WordPress exportierte Json-Dateien

Lesezeit: 12 Minuten

Benutzer-Avatar
Anders Kitson

Ich habe zwei Json-Dateien, die ich aus WordPress exportiert habe und die entsprechende IDs haben. Ich möchte sie in einer Json-Datei kombinieren, damit ich sie in die Website bringen kann, die ich mit Gatsby JS baue. Eine der Dateien ist die posts.json und der andere ist postsMeta.json. Die post_id in BeiträgeMeta entspricht der ID in Beiträge

Wie würde ich am besten vorgehen, um die beiden zusammenzuführen? Kann ich irgendeine Art von ausführen for loop in js und wie würde ich das machen? Ich bin unter Windows, gibt es eine Art JSON-Explorer, der mir dabei helfen könnte.

Schließlich möchte ich auch einige der unnötigen Felder wie z post_parent in dem Beiträge json und so etwas wie die meta_key in dem BeiträgeMeta json.

Ok, hoffentlich ist das klar genug, danke im Voraus.

Hier ist ein Beispiel für die dem ersten Objekt entsprechenden Paare in den beiden Dateien

posts.json

{"ID":"19","post_author":"2","post_date":"2010-12-31 23:02:04","post_date_gmt":"2010-12-31 23:02:04","post_content":"Harry Potter was not available for the first sitting of the Halloween Picture. I hope everyone had a safe and fun Halloween. Tomorrow is picture retake day, please send back your previous prints if you want retakes. It is also hot lunch. See You tomorrow!","post_title":"Happy Halloween","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"open","post_password":"","post_name":"happy-halloween","to_ping":"","pinged":"","post_modified":"2011-01-03 05:26:11","post_modified_gmt":"2011-01-03 05:26:11","post_content_filtered":"","post_parent":"0","guid":"http:\/\/localhost\/mrskitson.ca_wordpress\/?p=19","menu_order":"0","post_type":"post","post_mime_type":"","comment_count":"1"},

postsMeta.json

{"meta_id":"27","post_id":"19","meta_key":"large_preview","meta_value":"http:\/\/www.mrskitson.ca\/wp-content\/uploads\/2010\/12\/halloween.jpg"},

Aktualisieren:

Dies ist ein Versuch, dieses Problem mit der aktuellen Antwort zu lösen, Sie können den Code dort bearbeiten.

  • Sehr interessanter Beispielcode, den Ihre Frage in den Antworten unten erzeugt hat, +1 für alle 🙂

    – Brasilo

    10. Mai 2018 um 6:08 Uhr

  • Erstellen Sie einen neuen JSON mit den benötigten Feldern, durchlaufen Sie den ersten JSON und prüfen Sie jede Zeile im zweiten JSON. Wenn die Schlüssel übereinstimmen, füllen Sie die aktuelle „Zeile“ im neuen JSON aus und beginnen Sie dann mit der zweiten „Zeile“. der erste json.

    – WltrRpo

    11. Mai 2018 um 20:32 Uhr

Wie würde ich am besten vorgehen, um die beiden zusammenzuführen?

Ist es obligatorisch für Sie kombinieren die beiden JSON-Dateien/Daten?

Denn Sie könnten die JSON-Daten einfach aus Ihrem Skript heraus anfordern oder laden (oder sie sogar in die HTML) und dann den Metawert eines bestimmten Metafelds/Schlüssels zu erhalten, this function könnte das:

// `single` has no effect if `meta_key` is empty.
function getPostMeta( post_id, meta_key, single ) {
    let id = String( post_id ),
        pm = [];
    postsMeta.map( m => {
        let a = ( ! meta_key ) ||
            ( meta_key === m.meta_key );

        if ( a && id === m.post_id ) {
            pm.push( m );
        }
    });

    let meta = {},
        mk = {};
    pm.map( m => {
        let k = m.meta_key, v;

        if ( undefined === meta[ k ] ) {
            meta[ k ] = m.meta_value;
        } else {
            v = meta[ k ];
            if ( undefined === mk[ k ] ) {
                meta[ k ] = [ v ];
                mk[ k ] = 1;
            }

            meta[ k ].push( m.meta_value );
            m[ k ]++;
        }
    });

    pm = null;
    mk = meta_key ? mk[ meta_key ] : null;

    if ( mk ) {
        return single ?
            meta[ meta_key ][0] : // Returns a single meta value.
            meta[ meta_key ];     // Returns all the meta values.
    }

    return meta_key ?
        meta[ meta_key ] : // Returns the value of the `meta_key`.
        meta;              // Or returns all the post's meta data.
}

Die Daten, die ich zum Testen verwendet habe: (beachten Sie die postsMeta in obigem/getPostMeta() Funktion)

// Array of `post` objects.
const posts = [{"ID":"19","post_author":"2","post_date":"2010-12-31 23:02:04","post_date_gmt":"2010-12-31 23:02:04","post_content":"Harry Potter was not available for the first sitting of the Halloween Picture. I hope everyone had a safe and fun Halloween. Tomorrow is picture retake day, please send back your previous prints if you want retakes. It is also hot lunch. See You tomorrow!","post_title":"Happy Halloween","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"open","post_password":"","post_name":"happy-halloween","to_ping":"","pinged":"","post_modified":"2011-01-03 05:26:11","post_modified_gmt":"2011-01-03 05:26:11","post_content_filtered":"","post_parent":"0","guid":"http:\/\/localhost\/mrskitson.ca_wordpress\/?p=19","menu_order":"0","post_type":"post","post_mime_type":"","comment_count":"1"}];

// Array of `meta` objects.
const postsMeta = [{"meta_id":"27","post_id":"19","meta_key":"large_preview","meta_value":"http:\/\/www.mrskitson.ca\/wp-content\/uploads\/2010\/12\/halloween.jpg"},{"meta_id":"28","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/facebook.com"},{"meta_id":"29","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/twitter.com"},{"meta_id":"30","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/linkedin.com"}];

Beispiele: (vgl diese Geige für Demo)

// In these examples, we are retrieving the meta value for the post #19 (i.e. ID is 19).

// Retrieve a single value.
// Returns mixed; string, number, etc.
let url = getPostMeta( 19, 'large_preview', true );
console.log( url );

// Retrieve all meta values.
// Always returns an array of values.
let ms = getPostMeta( 19, 'many_values' );
console.log( ms, ms[0] );

// Retrieve all meta data.
// Always returns an object with meta_key => meta_value pairs. I.e. { key => value, ... }
let ma = getPostMeta( 19 );
console.log( ma, ma.large_preview, ma.many_values[0] );

Aber wenn Sie die JSON-Daten wirklich kombinieren müssen, können Sie Folgendes tun: (Siehe wieder Demo auf dieselbe Geige)

// Here we modify the original `posts` object.
posts.map( p => {
    // Add all the post's meta data.
    p.meta = getPostMeta( p.ID );

    // Delete items you don't want..
    delete p.post_parent;
    delete p.menu_order;
    // delete ...;
});

console.log( JSON.stringify( posts[0].meta ) ); // posts[0].meta = object
console.log( posts[0].post_parent, posts[0].menu_order ); // both are undefined

Und dann, wenn Sie die neue/zusammengeführt JSON-Daten:

JSON.stringify( posts );

Aber Wenn Sie tatsächlich nur etwas mit dem Meta des Beitrags tun möchten, können Sie die posts widersprechen und die Sache tun; z.B:

// Here the original `posts` object is not modified, and that we don't
// (though you can) repeatedly call `getPostMeta()` for the same post.
posts.map( p => {
    // Get all the post's meta data.
    let meta = getPostMeta( p.ID );

    // Do something with `meta`.
    console.log( meta.large_preview );
});

console.log( JSON.stringify( posts[0].meta ) ); // posts[0].meta = undefined
console.log( posts[0].post_parent, posts[0].menu_order ); // both still defined

// posts[0].meta wouldn't be undefined if of course posts[0] had a `meta` item,
// which was set in/via WordPress...

Benutzer-Avatar
Josh aus Qaribu

Wenn Sie dies in js tun können, gibt es einen ziemlich einfachen Ansatz mit Array#map. Wenn Sie Ihre Frage vereinfachen, fragen Sie wirklich, wie Sie diese Metadaten unter jedem Eintrag in Beiträgen hinzufügen und nur die gewünschten Felder erhalten.

Ich gehe davon aus, dass posts.json tatsächlich ein Array ist (zB [{"ID":"19"....).

// Load these server-side, fetch them remotely, copy-paste, etc.
// I'll require them here for simplicity
const posts = require('./posts.json');
const postsMeta = require('./postsMeta.json');

// Build a Map so we can quickly look up the metas by post_id
// Extract what we need by destructuring the args
const metaByPost = postsMeta.reduce((a, {
  post_id: id,
  meta_value: value,
}) => a.set(id, {
  value,
  /* anything else you want in here */,
}), new Map());

const mergedPosts = posts.map(post => ({
  // Spread in the post
  ...post,
  // Spread in the meta content
  ...metaByPost.get(post.ID),
  // Undefine the props we don't want
  post_parent: undefined,
}));

I don’t love manually setting stuff to undefined — I think it’s nicer to explicitly say what props you’re going to include, instead of loading everything and undefining certain props.

  • A little stuck here already. If i need to load these files server side, I am thinking to use meteor place them in the server folder and import them by path, or do I still use the const posts format I also I don’t know what to put in the section mergedPosts it says Spread in the post, do I literally just put the value post… so on does this mean the mergedPosts variable going to be an array of the two combined json files?

    – Anders Kitson

    Apr 30, 2018 at 22:52

  • @AndersKitson take a look at this for more info on spreads: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – Josh from Qaribou

    May 1, 2018 at 1:56

  • What that code’s doing is taking the properties in post, the properties in the meta content for that post, and building a new object of them both put together. Object props always are set to their last one, so post_parent: undefined will set it to undefined if it comes last.

    – Josh from Qaribou

    May 1, 2018 at 1:57

  • Ok so the ... is the actual spread syntax? I assumed you put that in as a fill in the missing part. Also when you say load these server side? Can I do that in Node js? Or in a framework like meteor, or do you suggest another way of doing so?

    – Anders Kitson

    May 1, 2018 at 2:09

  • I tried running this on glitch on the server side you can see it all here glitch.com/edit/#!/join/ca634d31-d3eb-4fe0-a8fb-cce34f4d862c I am getting a Map is not defined error

    – Anders Kitson

    May 3, 2018 at 22:35

user avatar
atmin

Try this snippet directly in the Chrome DevTools console:

(function(
  postsUrl="https://cdn.glitch.com/61300ea6-6cc4-4cb6-a62f-31adc62ea5cc%2Fposts.json?1525386749382",
  metaUrl="https://cdn.glitch.com/61300ea6-6cc4-4cb6-a62f-31adc62ea5cc%2Fpostmeta.json?1525386742630"
) {
  Promise.all([
    fetch(postsUrl).then(r => r.json()),
    fetch(metaUrl).then(r => r.json()),
  ]).dann(([postsResponse, metaResponse]) => { // Untersuchte die tatsächliche JSON-Antwort, um die Datenstruktur const posts = postsResponse zu erhalten[2].Daten;  const meta = metaResponse[2].Daten;  const metaByPostId = meta.reduce((accum, el) => { accum[el.post_id] = El;  Akku zurückgeben;  }, {});  const transformedPosts = posts.map(post => { const merged = { ...post, ...(metaByPostId[post.ID] ||  {}), };  merged.post_parent löschen;  // alle anderen Felder löschen, die im Ergebnis nicht erwünscht sind return merged;  });  console.log (transformierte Beiträge);  });  })();
  • URLs entsprechend ersetzen, ich habe die aus dem Glitch-Beispiel hier verwendet
  • Wie kommentiert, sind die tatsächlichen Daten darin vergraben response[2].data. Verwenden Sie die Registerkarte Netzwerk / Geparste Ansicht, um die Struktur anzuzeigen
  • ersetzen console.log mit copywenn das Ergebnis in die Zwischenablage kopiert werden soll, anstatt in der Konsole protokolliert zu werden

  • Hey danke für die Hilfe, ich bekomme eine TypeError: meta is undefined wenn Sie dies lokal ausführen. Ich habe versucht, es auf Glitch auszuführen, aber ich habe eine Fehlermeldung erhalten The page’s settings blocked the loading of a resource Haben Sie irgendwelche Ideen.

    – Anders Kitson

    10. Mai 2018 um 2:10 Uhr

  • Das bedeutet höchstwahrscheinlich die Aufforderung zu metaUrl scheitert und dann const meta = metaResponse[2].data scheitert. Sie können dies herausfinden, indem Sie Devtools / Network beobachten. Könnte eine Browsererweiterung sein, versuchen Sie es mit einer Inkognito-Sitzung. Ich habe es gerade mit Chrome versucht und es funktioniert bei mir. Alternativ erhalten Sie nur die innere Funktion (const posts = JSON.parse('<your data here >'); const meta = JSON.parse('<meta data>'); ........ console.log(...);Notiz 2x hinzugefügt JSON.parse) und führe das aus, um das Netzwerk überhaupt zu überspringen.

    – atmin

    11. Mai 2018 um 7:40 Uhr


  • Ok, das schien zu funktionieren, aber ich sehe das nicht meta_value von dem postsMeta.json Datei IE: die Bild-Bild-URL aus der postsMeta Das ist eine der wichtigsten, die ich brauche, um im Finale zu stehen transformedPosts Das transformedPosts scheint nur eine der JSON-Dateien zu sein, insbesondere die posts.json nicht die Verschmelzung der beiden.

    – Anders Kitson

    12. Mai 2018 um 21:36 Uhr

  • Oh, du hast recht, das ist ein Fehler, metaByPostId[post.post_id] sollte sein metaByPostId[post.ID]werde die Antwort korrigieren

    – atmin

    14. Mai 2018 um 10:01 Uhr

Benutzer-Avatar
Attersson

Auf den Punkt gebracht zu deiner Frage. Wir wollen:

  • verschmelzen var a = {/*some json*/} hinein var b = {/*another json*/}
  • Felder einschneiden var exclusions = ["post_parent","meta_key"]

Führen Sie die JSONS zusammen

Zuerst müssen wir a und b füllen. Ihre JSONs können mit in Javascript-Objekte geparst werden JSON.parse():

let a = JSON.parse(/*JSON here*/);
let b = JSON.parse(/*JSON here*/);

Da Eigenschaften in Javascript definiert werden, überschreibt die zweite Definition die erste, wenn Sie eine Eigenschaft erneut definieren. Ihre JSONs enthalten nur Zeichenfolgen als Schlüssel und Zeichenfolgen als Werte, sodass eine flache Kopie ausreicht. Object.assign() kopiert alle Eigenschaften (Feld und Werte) in das erste Argument und gibt das letzte Objekt zurück. Daher wird a mit b zusammengeführt, vorausgesetzt, sie haben unterschiedliche Schlüssel, sonst überschreiben die Werte in b die Werte in a:

a = Object.assign(a,b);

Andernfalls, wenn sie nicht disjunkt sind, müssen Sie eine Richtlinie zum Beitreten definieren, z. B. können Sie eine priorisieren. Unten behalten wir die Werte stattdessen in a:

a = Object.assign(b,a);

Da Sie a erwähnt haben for Schleife, Die Zeile darunter macht dasselbe wie zwei Codezeilen darüber und zeigt Ihnen auch ein Beispiel, wie Sie Ihren eigenen benutzerdefinierten Lambda-Ausdruck schreiben können:

Object.keys(a).forEach(k=>b[k]=b[k]?b[k]:a[k]);

Nicht anfassen wollen a und b? Erstellen Sie ein drittes Objekt c.

let c = Object.assign({},a,b)

Zuletzt (warten Sie, bis der folgende Trimmschritt abgeschlossen ist) JSON.stringify() konvertiert Ihr zusammengeführtes Objekt wieder in JSON.

Ausschlüsse trimmen

Nach dem dritten Beispiel haben wir c mit allen Feldern zusammengeführt.

Zuerst ein kleiner Hack von hier:

Object.filter = (obj, predicate) => Object.keys(obj)
    .filter( key => predicate(obj[key]))
    .reduce( (res, key) => (res[key] = obj[key], res), {} );

Jetzt haben Objekte, genau wie Arrays, einen Filterprototyp, der einen erweiterten Objektprototyp hat. Es ist nicht wirklich die beste Vorgehensweise, da dies jedes Objekt erweitert, aber diese Funktion funktioniert in Bezug auf die Semantik von Javascript recht gut, und dieses Beispiel dient als Gelegenheit, eleganten Code im Javascript-Stil beizubehalten:

c = Object.filter(c, key=> !exclusions.includes(key) );

Voit-lá, fertig.

Wie für definiertes Object.filter() verwendet es Array.filter() und Array.reduzieren () . Klicken Sie zum Nachschlagen, für Ihre Bequemlichkeit.

1376370cookie-checkKombinieren Sie zwei aus WordPress exportierte Json-Dateien

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy