come convertire la stringa in valori numerici in mongodb

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:

  1. parseInt () memorizzerà il doppio tipo di dati in mongodb. Si prega di utilizzare il nuovo numeroInt (stringa).
  2. nel comando della shell Mongo per l’utilizzo di massa, la resa non funzionerà. Per favore NON aggiungere “resa”.
  3. Se già si modifica la stringa in double da parseInt (). Sembra che tu non abbia modo di cambiare il tipo in int direttamente. La soluzione è un po ‘cablata: cambia da double a string e poi cambia di nuovo in int con il nuovo NumberInt ().

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)