Per impostazione predefinita, tutti i "numeri" sono archiviati come "doppi" in MongoDB a meno che non vengano generalmente espressi in modo eccessivo.
Prendi i seguenti campioni:
db.sample.insert({ "a": 1 })
db.sample.insert({ "a": NumberLong(1) })
db.sample.insert({ "a": NumberInt(1) })
db.sample.insert({ "a": 1.223 })
Questo produce una raccolta come questa:
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }
Nonostante le diverse funzioni del costruttore, nota come molti dei punti dati presenti siano più o meno gli stessi. La stessa shell MongoDB non sempre distingue chiaramente tra loro, ma c'è un modo per dirlo.
C'è ovviamente il $type
operatore di query, che consente la selezione di tipi BSON.
Quindi testarlo con il tipo 1, che è "doppio":
> db.sample.find({ "a": { "$type": 1 } })
{ "_id" : ObjectId("559bb1b4a23c8a3da73e0f76"), "a" : 1 }
{ "_id" : ObjectId("559bb30fa23c8a3da73e0f7a"), "a" : 1.223 }
Vedi che sono selezionati sia il primo inserto che l'ultimo, ma ovviamente non gli altri due.
Quindi ora prova per BSON Type 16, che è un intero a 32 bit
> db.sample.find({ "a": { "$type": 16 } })
{ "_id" : ObjectId("559bb29aa23c8a3da73e0f79"), "a" : 1 }
Quello era il "terzo" inserimento che utilizzava NumberInt()
funzione nella shell. In modo che quella funzione e altra serializzazione dal tuo driver possano impostare questo tipo BSON specifico.
E per il tipo BSON 18, che è un numero intero a 64 bit
> db.sample.find({ "a": { "$type": 18 } })
{ "_id" : ObjectId("559bb1bba23c8a3da73e0f77"), "a" : NumberLong(1) }
Il "secondo" inserimento che è stato costruito tramite NumberLong()
.
Se volessi "eliminare" le cose che "non erano un doppio", allora faresti:
db.sample.find({ "$or": [{ "a": { "$type": 16 } },{ "a": { "$type": 18 } }]})
Quali sono gli unici altri tipi numerici validi diversi dallo stesso "doppio".
Quindi, per "convertire" questi nella tua raccolta, puoi elaborare "in blocco" in questo modo:
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();
Ciò che fa viene eseguito in tre passaggi "in blocco":
- Ritrasforma il valore in un nuovo campo come "doppio"
- Rimuovi il vecchio campo con il tipo indesiderato
- Rinomina il nuovo campo con il vecchio nome del campo
Questo è necessario poiché le informazioni sul tipo BSON sono "appiccicose" all'elemento campo una volta creato. Quindi per "ritrasmettere" è necessario rimuovere completamente i vecchi dati che includono l'assegnazione del campo originale.
Quindi questo dovrebbe spiegare come "rilevare" e anche "ritrasmettere" i tipi indesiderati nei tuoi documenti.