Sto provando a convertire una stringa che contiene un valore numerico al suo valore in una query aggregata in MongoDB.
Esempio di documento
{ "_id": ObjectId("5522XXXXXXXXXXXX"), "Date": "2015-04-05", "PartnerID": "123456", "moop": "1234" }
Esempio della query aggregata che utilizzo
{ aggregate: 'my_collection', pipeline: [ {$match: { Date : {$gt:'2015-04-01', $lt: '2015-04-05' }} }, {$group: {_id: "$PartnerID", total:{$sum:'$moop'} }}]}
dove sono i risultati
{ "result": [ { "_id": "123456", "total": NumberInt(0) } }
Come puoi convertire la stringa nel suo valore numerico?
Aggregazione MongoDB non consentita per modificare il tipo di dati esistente dei campi dati. In questo caso dovresti creare un codice di programmazione per convertire string
in int
. Controlla sotto il codice
db.collectionName.find().forEach(function(data) { db.collectionName.update({ "_id": data._id, "moop": data.moop }, { "$set": { "PartnerID": parseInt(data.PartnerID) } }); })
Se le dimensioni delle tue raccolte superiori a quelle dello script rallenteranno le prestazioni, per perfomace mongo fornirà le operazioni bulk di mongo , usando le operazioni bulk di mongo anche il tipo di dati aggiornato
var bulk = db.collectionName.initializeOrderedBulkOp(); var counter = 0; db.collectionName.find().forEach(function(data) { var updoc = { "$set": {} }; var myKey = "PartnerID"; updoc["$set"][myKey] = parseInt(data.PartnerID); // queue the update bulk.find({ "_id": data._id }).update(updoc); counter++; // Drain and re-initialize every 1000 update statements if (counter % 1000 == 0) { bulk.execute(); bulk = db.collectionName.initializeOrderedBulkOp(); } }) // Add the rest in the queue if (counter % 1000 != 0) bulk.execute();
Ciò riduce sostanzialmente la quantità di istruzioni di operazioni inviate al server per inviare solo una volta ogni 1000 operazioni in coda.
You can easily convert the string data type to numerical data type. Don't forget to change collectionName & FieldName. for ex : CollectionNmae : Users & FieldName : Contactno.
Prova questa query ..
db.collectionName.find().forEach( function (x) { x.FieldName = parseInt(x.FieldName); db.collectionName.save(x); });
Alla fine ho usato
db.my_collection.find({moop : {$exists : true}}).forEach( function(obj) { obj.moop = new NumberInt( obj.moop ); db.my_collection.save(obj); } );
per trasformare moop
da stringa a intero in my_collection seguendo l’esempio nella risposta di Simone MongoDB: Come cambiare il tipo di un campo? .
Tre cose devono preoccuparsi di:
La stringa può essere convertita in numeri in MongoDB v4.0 utilizzando l’operatore $ toInt . In questo caso
db.col.aggregate([ { $project: { _id: 0, moopNumber: { $toInt: "$moop" } } } ])
uscite:
{ "moopNumber" : 1234 }
Dovrebbe essere salvato. Dovrebbe essere così:
db. my_collection.find({}).forEach(function(theCollection) { theCollection.moop = parseInt(theCollection.moop); db.my_collection.save(theCollection); });
Usando MongoDB 4.0 e successivi
Hai due opzioni, ad esempio $toInt
o $convert
. Usando $toInt
, segui l’esempio seguente:
filterDateStage = { '$match': { 'Date': { '$gt': '2015-04-01', '$lt': '2015-04-05' } } }; groupStage = { '$group': { '_id': '$PartnerID', 'total': { '$sum': { '$toInt': '$moop' } } } }; db.getCollection('my_collection').aggregate([ filterDateStage, groupStage ])
Se l’operazione di conversione rileva un errore, l’operazione di aggregazione si interrompe e genera un errore. Per sovrascrivere questo comportamento, utilizzare invece $convert
.
Usando $convert
groupStage = { '$group': { '_id': '$PartnerID', 'total': { '$sum': { '$convert': { 'input': '$moop', 'to': 'int' } } } } };
Usando Mappa / Riduci
Con map / reduce puoi usare le funzioni javascript come parseInt()
per fare la conversione. Ad esempio, è ansible definire la funzione della mappa per elaborare ogni documento di input: Nella funzione, this
riferisce al documento che l’operazione di riduzione della mappa sta elaborando. La funzione associa il valore della stringa moop
convertito al PartnerID
per ciascun documento ed emette il PartnerID
e la coppia moop
convertita. Qui è dove può essere applicata la funzione nativa JavaScript parseInt()
:
var mapper = function () { var x = parseInt(this.moop); emit(this.PartnerID, x); };
Quindi, definire la funzione di riduzione corrispondente con due argomenti keyCustId
e valuesMoop
. valuesMoop
è un array i cui elementi sono i valori interi moop
emessi dalla funzione mappa e raggruppati da keyPartnerID
. La funzione riduce la matrice valuesMoop
alla sum dei suoi elementi.
var reducer = function(keyPartnerID, valuesMoop) { return Array.sum(valuesMoop); }; db.collection.mapReduce( mapper, reducer, { out : "example_results", query: { Date: { $gt: "2015-04-01", $lt: "2015-04-05" } } } ); db.example_results.find(function (err, docs) { if(err) console.log(err); console.log(JSON.stringify(docs)); });
Ad esempio, con il seguente esempio di raccolta di documenti:
/* 0 */ { "_id" : ObjectId("550c00f81bcc15211016699b"), "Date" : "2015-04-04", "PartnerID" : "123456", "moop" : "1234" } /* 1 */ { "_id" : ObjectId("550c00f81bcc15211016699c"), "Date" : "2015-04-03", "PartnerID" : "123456", "moop" : "24" } /* 2 */ { "_id" : ObjectId("550c00f81bcc15211016699d"), "Date" : "2015-04-02", "PartnerID" : "123457", "moop" : "21" } /* 3 */ { "_id" : ObjectId("550c00f81bcc15211016699e"), "Date" : "2015-04-02", "PartnerID" : "123457", "moop" : "8" }
L’operazione precedente Map / Reduce salverà i risultati nella raccolta example_results
e il comando shell db.example_results.find()
darà:
/* 0 */ { "_id" : "123456", "value" : 1258 } /* 1 */ { "_id" : "123457", "value" : 29 }
La collazione è ciò di cui hai bisogno:
db.collectionName.find().sort({PartnerID: 1}).collation({locale: "en_US", numericOrdering: true})
db.user.find (). toArray (). filtro (a => a.age> 40)