![](/img/trans.png)
[英]Getting The entire node set is unreachable error when trying to connect to MongoDB with reactivemongo in my play2 application
[英]How should I structure my nested reactivemongo calls in my play2 application?
我正在尝试在我的play2应用程序中将一些嵌套调用与reactmongo结合在一起。 我得到从createObjects
返回的对象的列表。 然后,我遍历它们,检查对象是否存在于集合中,如果不存在,则将它们插入:
def dostuff() = Action {
implicit request =>
form.bindFromRequest.fold(
errors => BadRequest(views.html.invite(errors)),
form => {
val objectsReadyForSave = createObjects(form.companyId, form.companyName, sms_pattern.findAllIn(form.phoneNumbers).toSet)
Async {
for(object <- objectsReadyForSave) {
collection.find(BSONDocument("cId" -> object.get.cId,"userId" ->
object.userId.get)).cursor.headOption.map { maybeFound =>
maybeFound.map { found =>
Logger.info("Found record, do not insert")
} getOrElse {
collection.insert(object)
}
}
}
Future(Ok(views.html.invite(form)))
}
})
}
我觉得这种方式并不尽如人意,并且感觉不到“ play2”和“ reactivemongo”。 所以我的问题是:我应该如何构造嵌套的调用以获得所需的结果并获得有关已插入哪些对象的信息?
这是我改写的方式。
def dostuff() = Action { implicit request =>
form.bindFromRequest.fold(
errors => BadRequest(views.html.invite(errors)),
form => {
createObjects(form.companyId,
form.companyName,
sms_pattern.findAllIn(form.phoneNumbers).toSet).map(ƒ)
Ok(views.html.invite(form))
}
)
}
// ...
// In the model
// ...
def ƒ(cId: Option[String], userId: Option[String], logger: Logger) = {
// You need to handle the case where obj.cId or obj.userId are None
collection.find(BSONDocument("cId" -> obj.cId.get, "userId" -> obj.userId.get))
.cursor
.headOption
.map { maybeFound =>
maybeFound map { _ =>
logger.info("Record found, do not insert")
} getOrElse {
collection.insert(obj)
}
}
}
可能存在一些语法错误,但是想法就在那里。
我不是ReactiveMongo的mongoDB专家,但似乎您正在尝试以与使用标准SQL数据库相同的方式使用NoSQL数据库。 请注意,mongoDB是异步的,这意味着将来可能会执行操作,这就是为什么插入/更新操作不会返回受影响的文档的原因。 关于您的问题:
1要插入对象(如果不存在)并获得有关已插入哪些对象的信息?
您可能应该查看mongoDB的db.collection.update()方法,并将upsert
参数设置为true进行调用。 如果负担得起的话,这将更新文档(如果它们已经存在于数据库中),否则将其插入。 同样,此操作不会返回受影响的文档,但是您可以通过访问上一个错误来检查有多少文档受到了影响。 请参阅reactmongo.api.collections.GenericCollection#update ,它返回Future[LastError]
。
2对于所有插入的对象,将它们添加到列表中,然后通过Ok()调用将其返回。
再一次,将不会返回插入/更新的文档。 如果确实需要返回完整的受影响文档,则需要再次查询以检索匹配的文档。
我可能会用这种方式重写您的代码(没有错误/失败处理):
def dostuff() = Action {
implicit request =>
form.bindFromRequest.fold(
errors => BadRequest(views.html.invite(errors)),
form => {
val objectsReadyForSave = createObjects(form.companyId, form.companyName, sms_pattern.findAllIn(form.phoneNumbers).toSet)
Async {
val operations = for {
data <- objectsReadyForSave
} yield collection.update(BSONDocument("cId" -> data.cId.get, "userId" -> data.userId.get), data, upsert = true)
Future.sequence(operations).map {
lastErrors =>
Ok("Documents probably inserted/updated!")
}
}
}
)
}
另请参阅Scala期货: http : //docs.scala-lang.org/overviews/core/futures.html
这真的很有用! ;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.