ReactiveMongo BSONDouble vs BSONLong

时间:2014-05-19 12:13:48

标签: mongodb scala reactive-programming

我有一个大的csv文件,我通过iconv转换为UTF8然后加载到Mongo。我尝试使用ReactiveMongo / Scala查询数据时遇到很多错误。似乎有些记录的值为BSONDouble,有些则为BSONLong。检索查询会导致错误:如果我尝试切换,则无法将BSONDouble转换为BSONLong或其他方式。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

如果您没有显示某些代码,那么很难真正提供帮助。我假设您正在为您的文档撰写BSONDocumentReader,并且BSONDocument.getAs[A]ABSONDoubleBSONLong,并且当类型为&#39}时失败; t匹配。

一种方法是使用BSONDocument.getAsTry[A],它会返回Try[A],如果它是Failure你就知道你必须尝试其他类型。

答案 1 :(得分:0)

这让我远离了兔子洞。 mongoimport存储的一些数字不仅是BSONDouble或BSONLong还是BSONInteger,有些甚至是BSONString。我最初使用BSONNumberLike检查并且适用于小型数据集,但是当我切换到mongo中的较大数据集时,它会因Null指针异常而崩溃。在更多阅读并查看返回的BSON之后,此代码似乎更具防弹性(或者至少使用我的大型数据集):

case class Aggsecrow (
  Strategy: String,
  Security: String,
  LocalPosn: Double,
  USDPosn: Double,
  CurrentPx: Double,
  USDMV: Double,
  PNL: Double
)

object Aggsecrow {
  implicit object AggsecrowBSONReader extends BSONDocumentReader[Aggsecrow] {
    def safeNumGet(field: String, doc: BSONDocument): Double = {
      var dtry = doc.getAsTry[BSONNumberLike](field)
      var d = 0.0
      if(dtry.isFailure) {
        val stry = doc.getAsTry[BSONString](field)
        val strConv = stry.get.value
        val doubleConv = Double.valueOf(strConv).longValue
        d = doubleConv.doubleValue
      } else {
        d = try {dtry.get.toDouble} catch { case _ => 0.0}
      }
      d
    }

    def read(doc: BSONDocument) :Aggsecrow = {
      Aggsecrow(
        doc.getAsTry[String]("Strategy").get,
        doc.getAsTry[String]("Security").get,
        safeNumGet("LocalPosn",doc) ,
        safeNumGet("USDPosn",doc) ,
        safeNumGet("Current",doc) ,
        safeNumGet("USDMV",doc) ,
        safeNumGet("PNL",doc) ,
    }
  }

答案 2 :(得分:0)

运行测试时,我遇到了同样的问题。 但是,这是由“ DataLoader”引起的,该数据在测试之前将数据注入到db中。数据被注入为 json ,因此将'0'解释为Integer而不是Double。

在测试数据中将“ 0”更改为“ 0.1”足以迫使该类型在Mongo中为Double。现在,检索文档将值检索为BSONDouble。