sql >> Database >  >> NoSQL >> MongoDB

MongoDb - Type wijzigen van Int naar Double

Standaard worden alle "nummers" opgeslagen als "dubbel" in MongoDB, tenzij ze over het algemeen overmatig worden gegoten.

Neem de volgende voorbeelden:

db.sample.insert({ "a": 1 })
db.sample.insert({ "a": NumberLong(1) })
db.sample.insert({ "a": NumberInt(1) })
db.sample.insert({ "a": 1.223 })

Dit levert een verzameling op zoals deze:

{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }

Merk ondanks de verschillende constructorfuncties op hoe verschillende datapunten er ongeveer hetzelfde uitzien. De MongoDB-shell zelf maakt niet altijd duidelijk onderscheid tussen hen, maar er is een manier om het te zien.

Er is natuurlijk de $type query-operator, waarmee u BSON-typen kunt selecteren.

Dus dit testen met Type 1 - Wat "dubbel" is:

> db.sample.find({ "a": { "$type": 1 } })
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }

Je ziet dat zowel de eerste als de laatste zijn geselecteerd, maar de andere twee natuurlijk niet.

Dus test nu voor BSON Type 16 - wat een 32-bits geheel getal is

> db.sample.find({ "a": { "$type": 16 } })
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }

Dat was de "derde" invoeging die de NumberInt() . gebruikte functie in de schil. Zodat functie en andere serialisatie van uw stuurprogramma dit specifieke BSON-type kan instellen.

En voor de BSON Type 18 - dat is 64-bit integer

> db.sample.find({ "a": { "$type": 18 } })
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }

De "tweede" invoeging die is gemaakt via NumberLong() .

Als je dingen die "geen dubbel" waren, zou willen "verwijderen", dan zou je het volgende doen:

db.sample.find({ "$or": [{ "a": { "$type": 16 } },{ "a": { "$type": 18 } }]})

Dit zijn de enige andere geldige numerieke typen dan "dubbel" zelf.

Dus om deze in uw verzameling te "converteren", kunt u dit als volgt "bulken":

var bulk = db.sample.initializeUnorderedBulkOp(),
    count = 0;
db.sample.find({ 
    "$or": [
        { "a": { "$type": 16 } },
        { "a": { "$type": 18 } }
    ]
}).forEach(function(doc) {
    bulk.find({ "_id": doc._id })
        .updateOne({ 
            "$set": { "b": doc.a.valueOf() } ,
            "$unset": { "a": 1 } 
        });
    bulk.find({ "_id": doc._id })
        .updateOne({ "$rename": { "b": "a" } });
    count++;
    if ( count % 1000 == 0 ) {
        bulk.execute()
        bulk = db.sample.initializeUnOrderedBulkOp();
    }
})
if ( count % 1000 != 0 ) bulk.execute();

Wat dat doet, wordt in drie stappen "in bulk" uitgevoerd:

  1. Creëer de waarde naar een nieuw veld als een "double"
  2. Verwijder het oude veld met het ongewenste type
  3. Hernoem het nieuwe veld naar de oude veldnaam

Dit is noodzakelijk omdat de informatie van het BSON-type "kleverig" is voor het veldelement dat eenmaal is gemaakt. Dus om te "re-casten" moet je de oude gegevens volledig verwijderen, inclusief de originele veldtoewijzing.

Dus dat zou moeten verklaren hoe u ongewenste typen in uw documenten kunt "detecteren" en ook "opnieuw casten".




  1. spring-boot redis :Hoe alle sessies van een gebruiker ongeldig maken?

  2. MongoDB uitvoeren met Ops Manager

  3. Inzicht in Hadoop High Availability-functie

  4. verwijder _id van mongo resultaat