2014-09-22 18 views
9

Ho una raccolta di documenti che hanno un valore noto per essere un numero, ma sono memorizzati come una stringa. È fuori dal mio controllo cambiare il tipo di campo, ma voglio usare quel campo in un'aggregazione (diciamo, per fare una media).Convertire una stringa in un numero nella proiezione MongoDB

Sembra che dovrei usare una proiezione prima del raggruppamento e in quella proiezione convertire il campo secondo necessità. Non riesco a trovare la sintassi giusta - tutto ciò che provo mi dà il NaN, o il nuovo campo manca semplicemente dal prossimo passo nell'aggregazione.

$project: { 
    value: '$value', 
    valueasnumber: ???? 
} 

Dato l'esempio molto semplice di cui sopra, in cui il contenuto di $ valore in tutti i documenti sono di tipo stringa, ma sarà analizzare ad un numero, che cosa devo fare per rendere valueasnumber un nuovo campo (inesistente) che è di tipo double con la versione analizzata di $ value in esso?

Ho provato cose come esempi che seguono (e circa una dozzina di cose simili):

{ $add: new Number('$value').valueOf() } 
new Number('$value').valueOf() 

Perchè sono abbaiare contro l'albero sbagliato tutto? Qualsiasi aiuto sarebbe molto apprezzato!

(Per essere chiaro al 100%, di seguito è come vorrei utilizzare il nuovo campo).

$group { 
    score: { 
     $avg: '$valueasnumber' 
    } 
} 
+1

A partire da MongoDB 2.6, sei sfortunato. Non ci sono opzioni di analisi del numero disponibili nel framework di aggregazione. Se il campo rappresenta un numero, dovrebbe essere effettivamente memorizzato come un numero; forse potresti aggiungere un altro campo che è la forma numerica del numero? Puoi anche considerare la mappa/ridurre. – wdberkeley

+0

Grazie per i commenti a tutti. Sto provando entrambi gli approcci per vedere cosa funziona meglio. Sembra che il framework di aggregazione abbia prestazioni migliori di map/reduce, quindi potrebbe valere la pena mantenere il secondo campo (come numero) in modo che l'aggregazione possa essere utilizzata come previsto. –

+0

Possibile duplicato di [come convertire la stringa in valori numerici in mongodb] (http://stackoverflow.com/questions/29487351/how-to-convert-string-to-numerical-values-in-mongodb) – styvane

risposta

3

Uno dei modi che posso pensare è quello di utilizzare una shell mongo javascript per modificare il documento aggiungendo nuovo campo numero, valuesasnumber (conversione numero di stringa esistente 'valore' campo) nel documento esistente o nel nuovo documento Quindi utilizzare questo campo numerico per ulteriori calcoli.

db.numbertest.find().forEach(function(doc) { 
    doc.valueasnumber = new NumberInt(doc.value); 
    db.numbertest.save(doc); 
}); 

Utilizzando il campo valueasnumber di calcolo numerico

db.numbertest.aggregate([{$group : 
    {_id : null, 
    "score" : {$avg : "$valueasnumber"} 
    } 
}]); 
2

L'operazione principale è quello di convertire il valore da stringa a numero che non riesce a manipolati in aggregate pipeline operation attualmente.
mapReduce è un'alternativa come di seguito.

db.c.mapReduce(function() { 
    emit(this.groupId, {score: Number(this.value), count: 1}); 
}, function(key, values) { 
    var score = 0, count = 0; 
    for (var i = 0; i < values.length; i++) { 
     score += values[i].score; 
     count += values[i].count; 
    } 
    return {score: score, count: count}; 
}, {finalize: function(key, value) { 
    return {score: value.score/value.count}; 
}, out: {inline: 1}}); 
Problemi correlati