价格存储为字符串的MongoDB$gt/$lt运算符



我试图在数据库中查询大于/小于用户指定数字的价格。在我的数据库中,价格是这样存储的:

{price: "300.00"}

根据文件,这应该有效:

db.products.find({price: {$gt:30.00}}).pretty()

但我没有得到任何结果。我也试过{price: {$gt:30}}

我在这里错过了什么?

是因为价格在数据库中存储为字符串而不是数字吗?有办法绕过这个吗?

如果您打算将$gt与字符串一起使用,则必须使用regex,这在性能方面并不好。只需创建一个包含price数字值的新字段或将此字段类型更改为int/double会更容易。javascript版本也应该起作用,比如:

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

因为js会在使用前将其转换为数字。但是,索引对此查询不起作用。

$gt是一个可以处理任何类型的运算符:

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

退货:

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

如果要与具有$gt$lt的数字进行比较,则文档中的值也需要是一个数字。MongoDB中的类型是严格的,并且不会像在PHP中那样自动转换。为了解决您的问题,请确保将价格存储为数字(浮点或整数):

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

退货:

{ "_id" : ObjectId("51ffbf2016473d7b84172d5b"), "price" : 50.4 }

Mongo 4.0开始,有一个新的$toDouble聚合运算符,它可以从各种类型转换为double(在本例中是从字符串转换):

// { price: "300.00" }
// { price: "4.2" }
 db.collection.find({ $expr: { $gt: [{ $toDouble: "$price" }, 30] } })
// { price: "300.00" }

如果你有更新版本的mongodb,那么你可以这样做:

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

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

$convert操作器:https://docs.mongodb.com/manual/reference/operator/aggregation/convert/index.html

或者,您可以将值转换为Int,如下所示: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)

最新更新