sql >> Databáze >  >> NoSQL >> MongoDB

MongoDb - Změňte typ z Int na Double

Ve výchozím nastavení jsou všechna „čísla“ v MongoDB uložena jako „dvojitá“, pokud nejsou obecně přetypována.

Vezměte následující vzorky:

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

Výsledkem je kolekce podobná této:

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

Navzdory různým funkcím konstruktoru si všimněte, že několik datových bodů tam vypadá téměř stejně. Samotný MongoDB shell mezi nimi ne vždy jasně rozlišuje, ale existuje způsob, jak to poznat.

Samozřejmostí je $type dotazovací operátor, který umožňuje výběr typů BSON.

Takže to otestujte s typem 1 – což je „dvojité“:

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

Vidíte, že je vybrána první i poslední vložka, ale samozřejmě ne další dvě.

Nyní tedy otestujte BSON Type 16 – což je 32bitové celé číslo

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

To bylo "třetí" vložení, které používalo NumberInt() funkce ve skořápce. Takže tato funkce a další serializace z vašeho ovladače mohou nastavit tento konkrétní typ BSON.

A pro BSON Type 18 – což je 64bitové celé číslo

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

"Druhé" vložení, které bylo vytvořeno pomocí NumberLong() .

Pokud byste chtěli „vyřadit“ věci, které „nebyly dvojité“, udělali byste:

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

Což jsou jediné další platné číselné typy kromě samotného "double".

Chcete-li je tedy „převést“ ve své sbírce, můžete „hromadně“ zpracovat takto:

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();

To, co dělá, se provádí ve třech krocích „hromadně“:

  1. Znovu přetypujte hodnotu do nového pole jako "double"
  2. Odstraňte staré pole s nežádoucím typem
  3. Přejmenujte nové pole na starý název pole

To je nezbytné protože informace o typu BSON je "přilepená" k prvku pole, jakmile je vytvořen. Chcete-li tedy „přetypovat“, musíte úplně odstranit stará data, která zahrnují původní přiřazení pole.

To by tedy mělo vysvětlovat, jak „odhalit“ a také „přeobsadit“ nežádoucí typy ve vašich dokumentech.




  1. Problémy se spouštěním příkladů v Meteoru

  2. mongodb:nalezení nejvyšší číselné hodnoty sloupce

  3. mapování v create index v elasticsearch through mongodb river se neprojeví

  4. Operátor agregačního potrubí MongoDB $lt