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

JVG*_*JVG 25 mongodb

我正在尝试查询我的数据库中的价格是否大于/小于用户指定的数字.在我的数据库中,价格存储如下:

{price: "300.00"}
Run Code Online (Sandbox Code Playgroud)

根据文档,这应该工作:

db.products.find({price: {$gt:30.00}}).pretty()
Run Code Online (Sandbox Code Playgroud)

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

我在这里错过了什么?

这是因为价格存储为字符串而不是数据库中的数字?有没有解决的办法?

Jay*_*ayz 24

如果您打算将$ gt与字符串一起使用,则必须使用正则表达式,这在性能方面并不是很好.创建一个包含价格数值的新字段或将此字段类型更改为int/double更容易.一个javascript版本也应该工作,如下所示:

db.products.find("this.price > 30.00")
Run Code Online (Sandbox Code Playgroud)

因为js会在使用前将其转换为数字.但是,索引不适用于此查询.

  • 哇,不知道您可以在查询中使用 javascript。很好,谢谢。无论如何,我都会将其转换为数字,但这很有帮助。 (2认同)
  • 请避免使用$ where,它在JavaScript中运行并且性能受到很大影响.$ gt也可以与其他类型一起使用. (2认同)

Der*_*ick 20

$gt 是一个可以在任何类型上工作的运算符:

db.so.drop();
db.so.insert( { name: "Derick" } );
db.so.insert( { name: "Jayz" } );
db.so.find( { name: { $gt: "Fred" } } );
Run Code Online (Sandbox Code Playgroud)

返回:

{ "_id" : ObjectId("51ffbe6c16473d7b84172d58"), "name" : "Jayz" }
Run Code Online (Sandbox Code Playgroud)

如果要与带$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 } } );
Run Code Online (Sandbox Code Playgroud)

返回:

{ "_id" : ObjectId("51ffbf2016473d7b84172d5b"), "price" : 50.4 }
Run Code Online (Sandbox Code Playgroud)


Xav*_*hot 13

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

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


Tom*_*iha 5

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

$expr: {
          $gt: [
             { $convert: { input: '$price', to: 'decimal' } },
             { $convert: { input: '0.0', to: 'decimal' } }
               ]
              }
Run Code Online (Sandbox Code Playgroud)

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

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