MongoDB $gt/$lt operators with prices stored as strings

后端 未结 5 1279
一生所求
一生所求 2020-11-29 06:27

I\'m trying to query my database for prices greater than/less than a user specified number. In my database, prices are stored like so:

{price: \"300.00\"}


        
相关标签:
5条回答
  • 2020-11-29 07:07

    $gt is an operator that can work on any type:

    db.so.drop();
    db.so.insert( { name: "Derick" } );
    db.so.insert( { name: "Jayz" } );
    db.so.find( { name: { $gt: "Fred" } } );
    

    Returns:

    { "_id" : ObjectId("51ffbe6c16473d7b84172d58"), "name" : "Jayz" }
    

    If you want to compare against a number with $gt or $lt, then the value in your document also needs to be a number. Types in MongoDB are strict and do not auto-convert like they f.e. would do in PHP. In order to solve your issue, make sure you store the prices as numbers (floats or ints):

    db.so.drop();
    db.so.insert( { price: 50.40 } );
    db.so.insert( { price: 29.99 } );
    db.so.find( { price: { $gt: 30 } } );
    

    Returns:

    { "_id" : ObjectId("51ffbf2016473d7b84172d5b"), "price" : 50.4 }
    
    0 讨论(0)
  • 2020-11-29 07:16

    If you have newer version of mongodb then you can do this:

    $expr: {
              $gt: [
                 { $convert: { input: '$price', to: 'decimal' } },
                 { $convert: { input: '0.0', to: 'decimal' } }
                   ]
                  }
    

    $expr operator: https://docs.mongodb.com/manual/reference/operator/query/expr/

    $convert opetator: https://docs.mongodb.com/manual/reference/operator/aggregation/convert/index.html

    0 讨论(0)
  • 2020-11-29 07:16

    Alternatively you can convert the values to Int, as per: http://www.quora.com/How-can-I-change-a-field-type-from-String-to-Integer-in-mongodb

    var convert = function(document){
    var intValue = parseInt(document.field, 10);
      db.collection.update(
        {_id:document._id}, 
        {$set: {field: intValue}}
      );
    }
    
    db.collection.find({field: {$type:2}},{field:1}).forEach(convert)
    
    0 讨论(0)
  • 2020-11-29 07:18

    Starting Mongo 4.0, there is a new $toDouble aggregation operator which converts from various types to double (in this case from a string):

    // { price: "300.00" }
    // { price: "4.2" }
     db.collection.find({ $expr: { $gt: [{ $toDouble: "$price" }, 30] } })
    // { price: "300.00" }
    
    0 讨论(0)
  • 2020-11-29 07:20

    If you intend to use $gt with strings, you will have to use regex, which is not great in terms of performance. It is easier to just create a new field which holds the number value of price or change this field type to int/double. A javascript version should also work, like so:

    db.products.find("this.price > 30.00")
    

    as js will convert it to number before use. However, indexes won't work on this query.

    0 讨论(0)
提交回复
热议问题