Scala и Casbah - ошибка: опция [com.mongodb.DBObject] не принимает параметры
Я пытаюсь получить документ и получить его атрибут. Когда я использую метод findOne, я ожидаю получить MongoDBObject, но я получаю Option[com.mongodb.DBObject]. Как из него получить атрибут? Можно ли вместо этого получить MongoDBObject?
scala> var col = MongoClient()("test")("counters")
col: com.mongodb.casbah.MongoCollection = MongoCollection({ "_id" : "some" , "value" : 0})
scala> var doc = col.findOne()
doc: Option[com.mongodb.DBObject] = Some({ "_id" : "some" , "value" : 0})
scala> doc("_id")
<console>:13: error: Option[com.mongodb.DBObject] does not take parameters
doc("_id")
^
scala>
3 ответа
Casbah API не знает содержимого вашей базы данных и не может быть уверен, что запрашиваемая вами запись действительно существует. В Java такой метод просто возвращает объект, который может быть null
, Это не рекомендуется в Скала в пользу безопаснее Option[T]
тип. Таким образом, вы вынуждены справиться с ситуацией, когда объект не существует. У вас есть несколько синтаксисов для этого (от худшего к лучшему:
Когда вы уверены, что объект есть - в противном случае будет выдано исключение
col.findOne().get
Когда вы хотите обработать оба случая:
col.findOne() match {
case Some(r) => //r is your record
case None => //record didn't exist
}
Когда вы хотите выполнить определенные операции с вашей записью (монадический стиль)
col.findOne().map(r => r("_id")).foreach(println)
Код выше напечатает _id
столбец только если такая запись найдена - и ничего не делать иначе.
Вы получаете Option[DBObject] из-за вероятности того, что объект, который вы пытаетесь найти, может отсутствовать в базе данных.
Вы можете обработать это с match
построить:
col.findOne() match{
case Some(doc) => doc("id")
case None => // not found
}
Вы получаете Option[DBObject]
потому что, возможно, ничего не найдено, и в целом вы хотите избежать возврата null в scala (и любом другом функциональном языке). Есть несколько способов воздействовать на результат. Чтобы просто получить результат вы можете позвонить get
, который выдаст исключение, если вы получите None
из вашего запроса. Тогда есть getOrElse
, который вы можете использовать для получения результата или значения по умолчанию, которое вы должны передать в вызов. И тогда есть orNull
, который возвращает вам либо результат, либо ноль, если его нет. Вы также можете использовать foreach
, если вы используете только результат для создания побочных эффектов, или map
, если вы хотите получить определенное значение, а затем, например, вызвать getOrElse
на полученный вариант.