2017-06-28 3 views
0

Ich habe einige Daten, die wie folgt aussehen:Wie restrukturieren Dokumente Felder in einem Array

{ 
    "name" : "someValue", 
    "date" : "someValue", 
    "age" : "someValue", 
    "price" : "someValue", 
    "salesComps" : [ 
    { 
     "sales_comp1" : "someValue", 
     "sales_comp1_dos" : "someValue", 
     "sales_comp1_units" : "someValue", 
     "sales_comp1_NOI_unit" : "someValue", 
     "sales_comp1_sales_pr_unit" : "someValue", 
     "sales_comp1_adj_SPrice" : "someValue", 
     "sales_comp1_cap_rate" : "someValue", 
    }, 
    { 
     "sales_comp2" : "someValue", 
     "sales_comp2_dos" : "someValue", 
     "sales_comp2_units" : "someValue", 
     "sales_comp2_NOI_unit" : "someValue", 
     "sales_comp2_sales_pr_unit" : "someValue", 
     "sales_comp2_adj_SPrice" : "someValue", 
     "sales_comp2_cap_rate" : "someValue", 
    }, 
    { 
     "sales_comp3" : "someValue", 
     "sales_comp3_dos" : "someValue", 
     "sales_comp3_units" : "someValue", 
     "sales_comp3_NOI_unit" : "someValue", 
     "sales_comp3_sales_pr_unit" : "someValue", 
     "sales_comp3_adj_SPrice" : "someValue", 
     "sales_comp3_cap_rate" : "someValue" 
    } 
    ] 
} 

:

{ 
    "name" : "someValue", 
    "date" : "someValue", 
    "age" : "someValue", 
    "price" : "someValue", 
    "sales_comp1" : "someValue", 
    "sales_comp1_dos" : "someValue", 
    "sales_comp1_units" : "someValue", 
    "sales_comp1_NOI_unit" : "someValue", 
    "sales_comp1_sales_pr_unit" : "someValue", 
    "sales_comp1_adj_SPrice" : "someValue", 
    "sales_comp1_cap_rate" : "someValue", 
    "sales_comp2" : "someValue", 
    "sales_comp2_dos" : "someValue", 
    "sales_comp2_units" : "someValue", 
    "sales_comp2_NOI_unit" : "someValue", 
    "sales_comp2_sales_pr_unit" : "someValue", 
    "sales_comp2_adj_SPrice" : "someValue", 
    "sales_comp2_cap_rate" : "someValue", 
    "sales_comp3" : "someValue", 
    "sales_comp3_dos" : "someValue", 
    "sales_comp3_units" : "someValue", 
    "sales_comp3_NOI_unit" : "someValue", 
    "sales_comp3_sales_pr_unit" : "someValue", 
    "sales_comp3_adj_SPrice" : "someValue", 
    "sales_comp3_cap_rate" : "someValue" 
} 

ich die sales_compX Werte in einen Array mit Namen salesComps als solche konsolidieren Was ist der einfachste Weg dies zu tun? Ich würde jede Antwort in entweder Mongoose- oder Mongodb-Codebeispielen schätzen!

Antwort

2

Zuerst durchlaufen Sie die Daten mit Object.keys() und warten Sie, bis die 'sales_comp' Daten auftauchen. Wenn es das Schlüsselwertpaar in ein Halteobjekt einfügt, löschen Sie diesen Eintrag aus den Hauptdaten. Sobald dies abgeschlossen ist, fügen Sie das Halteobjekt wieder in die Daten ein. So etwas wie dies ...

Die Daten ...

var data = { 
    "name" : "someValue", 
    "date" : "someValue", 
    "age" : "someValue", 
    "price" : "someValue", 
    "sales_comp1" : "someValue", 
    "sales_comp1_dos" : "someValue", 
    "sales_comp1_units" : "someValue", 
    "sales_comp1_NOI_unit" : "someValue", 
    "sales_comp1_sales_pr_unit" : "someValue", 
    "sales_comp1_adj_SPrice" : "someValue", 
    "sales_comp1_cap_rate" : "someValue", 
    "sales_comp2" : "someValue", 
    "sales_comp2_dos" : "someValue", 
    "sales_comp2_units" : "someValue", 
    "sales_comp2_NOI_unit" : "someValue", 
    "sales_comp2_sales_pr_unit" : "someValue", 
    "sales_comp2_adj_SPrice" : "someValue", 
    "sales_comp2_cap_rate" : "someValue", 
    "sales_comp3" : "someValue", 
    "sales_comp3_dos" : "someValue", 
    "sales_comp3_units" : "someValue", 
    "sales_comp3_NOI_unit" : "someValue", 
    "sales_comp3_sales_pr_unit" : "someValue", 
    "sales_comp3_adj_SPrice" : "someValue", 
    "sales_comp3_cap_rate" : "someValue" 
}; 

Der Code ...

// holding Object 
var tmpStorage = {}; 

// Loop through the data 
Object.keys(data).forEach(function(d) { 
    // look for 'sales_comp' keys 
    if (/sales_comp/.test(d)) { 
     // find which 'sales_comp' each 'd' 
     // belongs to with simple regex (allowing 
     // for more than single digits here) 
     var id = d.match(/sales_comp([\d]+)/)[1]; 
     // create a tmp property for tmpStorage object 
     // if it doesn't exist (which it wont on the 
     // the first pass) 
     tmpStorage['tmp'+id] = tmpStorage['tmp'+id] || {}; 
     // add the current key-value pair to the 
     // tmpStorage Object 
     tmpStorage['tmp'+id][d] = data[d]; 
     // remove the current key-value pair from the 
     // data object 
     delete data[d] 
    } 
}); 

Die jetzt 'Daten' Objekt sieht wie folgt aus ...

console.log('data:',data); 
/* => 
data: { 
    name: 'someValue', 
    date: 'someValue', 
    age: 'someValue', 
    price: 'someValue' 
} 
*/ 

Und das tmpStorage-Objekt sieht so aus ...

console.log('tmpStorage:',tmpStorage); 
/* => 
tmpStorage: { 
    tmp1: { 
    sales_comp1: 'someValue', 
    sales_comp1_dos: 'someValue', 
    sales_comp1_units: 'someValue', 
    sales_comp1_NOI_unit: 'someValue', 
    sales_comp1_sales_pr_unit: 'someValue', 
    sales_comp1_adj_SPrice: 'someValue', 
    sales_comp1_cap_rate: 'someValue' 
    }, 
    tmp2: { 
    sales_comp2: 'someValue', 
    sales_comp2_dos: 'someValue', 
    sales_comp2_units: 'someValue', 
    sales_comp2_NOI_unit: 'someValue', 
    sales_comp2_sales_pr_unit: 'someValue', 
    sales_comp2_adj_SPrice: 'someValue', 
    sales_comp2_cap_rate: 'someValue' 
    }, 
    tmp3: { 
    sales_comp3: 'someValue', 
    sales_comp3_dos: 'someValue', 
    sales_comp3_units: 'someValue', 
    sales_comp3_NOI_unit: 'someValue', 
    sales_comp3_sales_pr_unit: 'someValue', 
    sales_comp3_adj_SPrice: 'someValue', 
    sales_comp3_cap_rate: 'someValue' 
    } 
} 
*/ 

Jetzt ist es nur eine Frage der den Inhalt des 'tmpStorage' drängen in ein neues 'data.salesComps' Array

data.salesComps = Object.keys(tmpStorage).map(function(t) { 
    return tmpStorage[t]; 
}); 

Und nun 'Daten' sieht wie folgt aus ...

console.log('data:',data); 
/* => 
data: { 
    name: 'someValue', 
    date: 'someValue', 
    age: 'someValue', 
    price: 'someValue', 
    salesComps: [ 
    { sales_comp1: 'someValue', 
     sales_comp1_dos: 'someValue', 
     sales_comp1_units: 'someValue', 
     sales_comp1_NOI_unit: 'someValue', 
     sales_comp1_sales_pr_unit: 'someValue', 
     sales_comp1_adj_SPrice: 'someValue', 
     sales_comp1_cap_rate: 'someValue' 
    }, 
    { sales_comp2: 'someValue', 
     sales_comp2_dos: 'someValue', 
     sales_comp2_units: 'someValue', 
     sales_comp2_NOI_unit: 'someValue', 
     sales_comp2_sales_pr_unit: 'someValue', 
     sales_comp2_adj_SPrice: 'someValue', 
     sales_comp2_cap_rate: 'someValue' 
    }, 
    { sales_comp3: 'someValue', 
     sales_comp3_dos: 'someValue', 
     sales_comp3_units: 'someValue', 
     sales_comp3_NOI_unit: 'someValue', 
     sales_comp3_sales_pr_unit: 'someValue', 
     sales_comp3_adj_SPrice: 'someValue', 
     sales_comp3_cap_rate: 'someValue' 
    } 
    ] 
} 
*/ 

Es mag kompliziert aussehen, aber sobald Sie alle Kommentare entfernt haben, sehen Sie einen relativ einfachen zweistufigen Prozess - entfernen Sie die benötigten Daten und fügen Sie sie dann wieder in das gewünschte Format ein.

Hope that :) half

0

One Operationen aus sind wahrscheinlich am besten in der Mongo Shell getan, die die JavaScript-Umgebung hat, dies zu umgehen, ohne dass über Rückruf kümmern und Überlegungen versprechen.

Also das Beste, was hier zu tun ist, Schleife der Ergebnisse Sammlung und schreiben Sie auf die Sammlung über die .bulkWrite() Methode nach den Feldern in ein Array umzuwandeln:

var name = "collection"; 
var ops = []; 

db.getCollection(name).find().forEach(doc => { 

    var obj = Object.keys(doc).filter(k => /^sales_comp/.test(k)) 
    .map(k => ({ [k.match(/\d+/)[0]]: { [k.replace(/\d+/,"")]: doc[k] }})) 
    .reduce((acc,curr) => { 
     let a = Object.keys(curr)[0]; 
     if (!acc.hasOwnProperty(a)) 
     acc[a] = { }; 
     acc[a][Object.keys(curr[a])[0]] = curr[a][Object.keys(curr[a])[0]]; 
     return acc; 
    },{}); 

    // Un-comment and swap if you don't want to retain the index number 
    //var comps = Object.keys(obj).map(k => obj[k]) 
    var comps = Object.keys(obj).map(k => Object.assign({ "index": parseInt(k) },obj[k])); 

    var unset = Object.keys(doc).filter(k => /^sales_comp/.test(k)) 
     .reduce((acc,curr) => Object.assign(acc,({ [curr]: 1 })),{}); 

    ops.push({ 
     "updateOne": { 
     "filter": { "_id": doc._id }, 
     "update": { 
      "$unset": unset, 
      "$set": { "salesComps": comps } 
     } 
     }   
    }); 

    if (ops.length >= 500) { 
     db.getCollection(name).bulkWrite(ops); 
     ops = []; 
    } 
}); 

if (ops.length > 0) { 
    db.getCollection(name).bulkWrite(ops); 
    ops = []; 
} 

die jedes Dokument wie neu schreiben würde:

{ 
    "_id" : ObjectId("5954461a38470d375d40aca1"), 
    "name" : "someValue", 
    "date" : "someValue", 
    "age" : "someValue", 
    "price" : "someValue", 
    "salesComps" : [ 
     { 
      "index" : 1, 
      "sales_comp" : "someValue", 
      "sales_comp_dos" : "someValue", 
      "sales_comp_units" : "someValue", 
      "sales_comp_NOI_unit" : "someValue", 
      "sales_comp_sales_pr_unit" : "someValue", 
      "sales_comp_adj_SPrice" : "someValue", 
      "sales_comp_cap_rate" : "someValue" 
     }, 
     { 
      "index" : 2, 
      "sales_comp" : "someValue", 
      "sales_comp_dos" : "someValue", 
      "sales_comp_units" : "someValue", 
      "sales_comp_NOI_unit" : "someValue", 
      "sales_comp_sales_pr_unit" : "someValue", 
      "sales_comp_adj_SPrice" : "someValue", 
      "sales_comp_cap_rate" : "someValue" 
     }, 
     { 
      "index" : 3, 
      "sales_comp" : "someValue", 
      "sales_comp_dos" : "someValue", 
      "sales_comp_units" : "someValue", 
      "sales_comp_NOI_unit" : "someValue", 
      "sales_comp_sales_pr_unit" : "someValue", 
      "sales_comp_adj_SPrice" : "someValue", 
      "sales_comp_cap_rate" : "someValue" 
     } 
    ] 
} 

Dieser im Grunde wird das Dokument für die Namen des „Schlüssels“ mit "sales_comp" beginnend inspizieren und nach auf dem numerischen Teil der Zeichenfolge den Schlüssel basierten Akkumulieren und dass aus den Namen Abstreifen wird das Datum in ein Array für jeden anderen numerischen Wert umgewandelt.

Bei der tatsächlichen Verarbeitung der "Aktualisierung" für die Zielsammlung verwenden wir den Operator $unset für die Felder, die mit "sales_comp begannen, um diese aus dem Dokument zu entfernen.Dann verwenden wir den Operator $set mit dem transformierten Array, um die neue Eigenschaft zu erstellen.

Es gibt hier einige gebräuchliche Redewendungen mit .map(), .reduce() und .filter(), mit denen Sie vertraut sein sollten, wenn Sie mit Datenstrukturen in JavaScript arbeiten.

Verwandte Themen