2017-07-09 1 views
0

Ich habe eine Sammlung von Dokumenten über Entitäten, die status Eigenschaft haben, die 1 oder 0 sein könnte. Jedes Dokument enthält viele Daten und belegt Platz. Ich möchte die meisten Daten auf den Dokumenten mit status gleich 0 loswerden.Wie kann ich alle Dokumenteigenschaften außer einem oder zwei in mongodb aufheben?

Also, ich möchte jedes Dokument in der Sammlung, die wie

{ 
    _id: 234, 
    myCode: 101, 
    name: "sfsdf", 
    status: 0,  
    and: 23243423.1, 
    a: "dsf", 
    lot: 3234, 
    more: "efsfs", 
    properties: "sdfsd" 
} 

... zu viel kleiner

{ 
    _id: 234, 
    mycode: 101, 
    status: 0 
} 

So kann ich tun, im Grunde sieht

db.getCollection('docs').update(
    {'statusCode': 0}, 
    { 
     $unset: { 
      and: "", 
      a: "", 
      lot: "", 
      more: "", 
      properties: "" 
     } 
    }, 
    {multi:true} 
) 

Aber es gibt ungefähr 40 Eigenschaften, die eine riesige Liste wären, und ich bin auch nicht sicher, dass alle Objekte dem gleichen Schema folgen.

Gibt es eine Möglichkeit, alle außer zwei Eigenschaften zu deaktivieren?

+0

Sie sollten nur überschreiben statt unset. So etwas wie 'db.getCollection ('docs').update ( { 'status': 0}, { _id: 234, mycode: 101, Status: 0 } ) 'und Bulk-Schreib verwenden. – Veeram

+0

Ich dachte daran, aber das sind zwei Fehler: 1. Überschreiben funktioniert nicht mit Multi-Parameter. 2. Ich muss die '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ## –

+0

Tut mir leid, ich habe meinen Kommentar noch aktualisiert. Nochmal Überprüfen. – Veeram

Antwort

1

Das Beste, was Sie hier tun können, ist, tatsächlich alle möglichen Eigenschaften auf $unset zu werfen und es seinen Job machen zu lassen. Sie können solche Argumente nicht mit einem Platzhalter versehen, so dass es wirklich keinen besseren Weg gibt, ohne in eine andere Sammlung zu schreiben.

Wenn Sie sie nicht alle eingeben oder nicht alle kennen möchten, führen Sie einfach einen Prozess durch, um alle anderen Eigenschaften der obersten Ebene zu erfassen.

Sie können dies mit .mapReduce() zum Beispiel tun:

var fields = db.getCollection('docs').mapReduce(
    function() { 
    Object.keys(this) 
     .filter(k => k !== '_id' && k !== 'myCode') 
     .forEach(k => emit(k,1)) 
    }, 
    function() {}, 
    { 
    "out": { "inline": 1 } 
    } 
).results.map(o => o._id) 
.reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{}) 

Geben Ihnen ein Objekt mit den vollständigen Liste Feldern zu $unset bieten:

{ 
    "a" : "", 
    "and" : "", 
    "lot" : "", 
    "more" : "", 
    "name" : "", 
    "properties" : "", 
    "status" : "" 
} 

Und das aus allen möglichen Top genommen Ebenenfelder in der gesamten Sammlung.

Sie können mit .aggregate() in MongoDB 3.4 das gleiche tun $objectToArray mit:

var fields = db.getCollection('docs').aggregate([ 
    { "$project": { 
    "fields": { 
     "$filter": { 
     "input": { "$objectToArray": "$$ROOT" }, 
     "as": "d", 
     "cond": { 
      "$and": [ 
      { "$ne": [ "$$d.k", "_id" ] }, 
      { "$ne": [ "$$d.k", "myCode" ] }   
      ] 
     } 
     } 
    } 
    }}, 
    { "$unwind": "$fields" }, 
    { "$group": { 
    "_id": "$fields.k" 
    }} 
]).map(o => o._id) 
    .reduce((acc,curr) => Object.assign(acc,{ [curr]: "" }),{}); 

Was auch immer Sie Weg, um die Liste der Namen erhalten, dann einfach, sie zu $unset senden:

db.getCollection('docs').update(
    { "statusCode": 0 }, 
    { "$unset": fields }, 
    { "multi": true } 
) 

Bottom wie ist, dass $unset ist es egal, ob die Eigenschaften in dem Dokument vorhanden sind oder nicht, sondern werden sie einfach entfernen, wo sie existieren.


Der alternative Fall ist, einfach alles in eine neue Sammlung zu schreiben, wenn das auch Ihren Bedürfnissen entspricht. Dies ist eine einfache Verwendung von $out als Aggregationspipeline-Stufe:

Verwandte Themen