MongoDB: How to get N decimals precision in a quer

2019-03-02 01:54发布

问题:

Given the following documents in a MongoDB collection...

{ "_id": 1, "amount": { "value": 1.123456789999, "rate": 1.2 }}
{ "_id": 2, "amount": { "value": 2.9844, "rate": 1.2 }}
{ "_id": 3, "amount": { "value": 1.123876, "rate": 1.2 }}
{ "_id": 4, "amount": { "value": 3.3557886, "rate": 1.2 }}
{ "_id": 5, "amount": { "value": 1.12599976, "rate": 1.2 }}

... is it possible to select all those documents where amount is 1.12 (i.e. get 2 decimals precision in the query)?

回答1:

You can do this with the $where operator.

db.collection.find({ "$where": function() { 
    return Math.round(this.amount.value * 100)/ 100 === 1.12; 
    }
})

EDIT (after this comment)

In this case you should use the aggregation framework especially the $redact operator and this is much faster than the solution using $where

db.collection.aggregate([
    { "$redact": { 
        "$cond": [
            { "$eq": [
                { "$subtract": [ 
                    "$amount.value", 
                    { "$mod": [ "$amount.value",  0.01 ] }
                ]}, 
                0.03
            ]}, 
            "$$KEEP", 
            "$$PRUNE"
        ]
     }}
])


回答2:

You're effectively doing a range query where 1.12 <= value < 1.13, so you could do this as:

db.test.find({'amount.value': {$gte: 1.12, $lt: 1.13}})

Which is a truncation to 2 decimal places. If you want to round it, you'd be looking for 1.115 <= value < 1.125:

db.test.find({'amount.value': {$gte: 1.115, $lt: 1.125}})


回答3:

you can just use the regex operator

db.test.find({ value: { $regex: 1\.12[0-9]*}})


回答4:

Starting from the answer I got from user3100115, here below is the final soluton:

db.orders.find({ "$where": function() { return this.amount.value - (this.amount.value % 0.01) === 0.03; }})

I hope it helps.