使用 Mongo(ose) 从 NumberDecimal 中提取小数

Posted

技术标签:

【中文标题】使用 Mongo(ose) 从 NumberDecimal 中提取小数【英文标题】:Extract Decimal from NumberDecimal with Mongo(ose) 【发布时间】:2017-06-15 12:00:42 【问题描述】:

在存储货币值的数值模型中,MongoDB docs 状态:

使用 NumberDecimal() 构造函数从 mongo shell 分配和查询十进制值。

同样,在使用 Morphia Java 库时,BigDecimal 会自动作为 BigDecimal 插入。

我正在使用 Mongoose 在 Node 中查询 Mongo,并尝试提取存储为 NumberDecimal 的字段的数值。但是,该值奇怪地包含在查询结果中,我不确定如何通过 Mongo 或 Mongoose 提取它:

[  
     
      "openValue":  
         "$numberDecimal":"119.931"
      ,
      "timestamp":"2017-01-20T10:30:00.000Z"
   ,
     
      "openValue":  
         "$numberDecimal":"119.965"
      ,
      "timestamp":"2017-01-20T10:31:00.000Z"
   
]

我读过的一篇文章指出,在我的应用程序代码中使用 parseFloat() 将执行我想要的操作,但是遍历结果以执行此转换效率不高。避免迭代和转换意味着每次我想要它们的值时都在 NumberDecimals 上运行该函数,这很烦人。

有没有办法可以使用 Mongo 或 Mongoose 将上面的 JSON 查询结果转换为下面的内容?

[  
     
      "openValue": 119.931,
      "timestamp":"2017-01-20T10:30:00.000Z"
   ,
     
      "openValue": 119.965,
      "timestamp":"2017-01-20T10:31:00.000Z"
   ,
     
      "openValue": 119.975,
      "timestamp":"2017-01-20T10:32:00.000Z"
   
]

我尝试将字段选择为...openValue.$numberDecimal,但这不起作用。谢谢!

编辑:这是我的 Mongoose 架构:

var EquityHistoryModel = new Schema(
   _id: 
      equityIdentifier:  type: 
         exchange:  type: String, index: true ,
         symbol:  type: String, index: true 
      , index: true ,
      instant:  type: Date, index: true ,
      durationMinutes:  type: Number 
   ,
   open:  type: mongoose.Schema.Types.Decimal ,
   high:  type: mongoose.Schema.Types.Decimal ,
   low:  type: mongoose.Schema.Types.Decimal ,
   close:  type: mongoose.Schema.Types.Decimal ,
   volume:  type: Number ,
   isDividendAdjusted:  type: Boolean ,
   isSplitAdjusted:  type: Boolean 
,  collection: 'equityHistories', versionKey: false );

这是上面第一个 JSON 结果的 Mongoose 查询:

mongo.EquityHistoryModel.aggregate([  
     
      "$match":  
         "_id.equityIdentifier.exchange":passed_in,
         "_id.equityIdentifier.symbol":passed_in,
         "_id.instant":passed_in
      
   ,
     
      "$project":  
         "_id":0,
         "openValue":"$open",
         "timestamp":"$_id.instant"
      
   
],

【问题讨论】:

你能显示你的架构定义吗? @chridam 我添加了我的架构和我正在使用的查询! 【参考方案1】:

你也可以覆盖toJSON方法:

// Never return '__v' field and return the 'price' as String in the JSON representation
// Note that this doesn't effect `toObject`
EquityHistoryModel.set('toJSON', 
  getters: true,
  transform: (doc, ret) => 
    if (ret.price) 
      ret.price = ret.price.toString();
    
    delete ret.__v;
    return ret;
  ,
);

【讨论】:

【参考方案2】:

与我的预期相反,这些值似乎是自动提取的。对结果进行字符串化会自动将值包装在 NumberDecimal 中。请参阅下面手动放置输出的代码:

console.log(docs[0].openValue);
119.800
console.log(JSON.stringify(docs[0].openValue]);
"$numberDecimal":"119.800"

此外,由于 res.json 或 res.send 使用 stringify,我在发送查询结果方面遇到了困难。相反,我编写了一个替换函数并在 Node 中设置属性。

【讨论】:

我有类似的问题,您介意调查一下吗? ***.com/questions/53369688/…

以上是关于使用 Mongo(ose) 从 NumberDecimal 中提取小数的主要内容,如果未能解决你的问题,请参考以下文章

在节点js中请求mongo

通过 mongoose 将项目插入 mongo 数组

使用 geojson 和 mongoose 将多边形坐标插入 Mongo DB 时出错

如何删除转发时间戳? OSE 版本 Syslog-NG

epoll使用详解:epoll_createepoll_ctlepoll_waitclose

epoll使用详解:epoll_createepoll_ctlepoll_waitclose