我有一个大的csv文件,我通过iconv转换为UTF8然后加载到Mongo。我尝试使用ReactiveMongo / Scala查询数据时遇到很多错误。似乎有些记录的值为BSONDouble,有些则为BSONLong。检索查询会导致错误:如果我尝试切换,则无法将BSONDouble转换为BSONLong或其他方式。有什么想法吗?
答案 0 :(得分:2)
如果您没有显示某些代码,那么很难真正提供帮助。我假设您正在为您的文档撰写BSONDocumentReader
,并且BSONDocument.getAs[A]
致A
为BSONDouble
或BSONLong
,并且当类型为&#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。