Mongodb 我能';我无法从Scala Mongo查询中获取任何数据
我正在尝试从mongo db数据库检索一些数据。我已经设置了一个用户帐户,可以使用命令行工具检索一些数据:Mongodb 我能';我无法从Scala Mongo查询中获取任何数据,mongodb,scala,Mongodb,Scala,我正在尝试从mongo db数据库检索一些数据。我已经设置了一个用户帐户,可以使用命令行工具检索一些数据: C:\Program Files\MongoDB\Server\3.6\bin\mongo.exe" database.foocorp.com:27017/mydatabase -u salimfadhley -p secretpassowrd MongoDB shell version v3.6.3 connecting to: mongodb://database.foocorp.co
C:\Program Files\MongoDB\Server\3.6\bin\mongo.exe" database.foocorp.com:27017/mydatabase -u salimfadhley -p secretpassowrd
MongoDB shell version v3.6.3
connecting to: mongodb://database.foocorp.com:27017/mydatabase
MongoDB server version: 3.4.4
WARNING: shell and server versions do not match
> db.mycollection.find()
... got loads of data back ...
我能够从Python中查询相同的数据集,如下所示:
from pymongo import MongoClient
def main():
client = MongoClient(
'database.foocorp.com',
username='salimfadhley',
password='secretpassword',
authsource='dashboard',
authMechanism='SCRAM-SHA-1'
)
db = client.dashboard
collection = db["mycollection"]
print(collection.find_one())
if __name__ == "__main__":
main()
它第一次像预期的那样完美地工作
但现在我想从Scala做同样的事情:
import org.mongodb.scala.{Document, MongoClient, MongoCollection}
object ConnectionDemo extends App {
val dbHost = "database.foocorp.com"
val dbPort = 27017
val dbUserName = "salimfadhley"
val dbPassword = "secretpassword"
val dbName = "mydatabase"
val collectionName = "mycollection"
val mongoClient = MongoClient(s"mongodb://$dbUserName:$dbPassword@$dbHost:$dbPort/?authsource=$dbName")
val mongoDatabase = mongoClient.getDatabase(dbName)
val result = mongoDatabase.getCollection(collectionName).find()
result.subscribe(
(d:Document) => println(d.toJson()),
(e:Throwable) => println(s"An error occurred, ${e.getMessage}"),
() => println("Done")
)
我的期望是,这段代码应该为集合中的每件东西打印出一个项目。当我使用Robo3T和mongo shell提供的完全相同的凭证查询集合时,我得到了大量的结果,所以我希望在这里看到同样的结果
实际上,这段代码似乎什么都不做:它从不打印任何结果、错误甚至“完成”
此外,如果我故意输入错误的密码或主机名,它仍然完全不起作用。如果连接参数完全错误,我希望看到某种错误消息
我做错了什么 愚蠢的我,答案已经给出了。我所要做的就是等待结果发布,最简单的方法就是使用Scala的“wait”函数。愚蠢的我,答案已经给出了。我所要做的就是等待结果交付,最简单的方法是使用Scala的“wait”函数。正如您所指出的,问题是您没有等待数据库的响应。我在您的回答中看到,您使用了wait——虽然这是一种有效的做法,但如果您希望代码是异步的,那么您应该真正避免使用wait。当你的应用程序正在等待响应时,它实际上不能做任何其他事情 解决这个问题的一个常见方法是使用。未来的好处在于,在其核心,你假设在某个时刻会有一个响应,并且可以在未来等待完成时继续计算其他东西。如果你想使用未来的价值,你可以在它里面映射。这假设一旦将来完成了,您将对结果做一些事情。使用Future的一般示例:
import scala.concurrent.Future
// assuming you have a method called callDatabase in another class called connector
val thingToWaitFor: Future[String] = ???
thingToWaitFor.map {
thing => // do something with this thing (thing is now of type String)
}
如果您需要等待多个期货,则需要在所有外部期货上使用Scala的flatMap函数,并且只在最内部期货上使用map:
import scala.concurrent.Future
val thingToWaitFor1: Future[String] = ???
val thingToWaitFor2: Future[String] = ???
val thingToWaitFor3: Future[String] = ???
thingToWaitFor1.flatMap {
thing1 =>
thingToWaitFor2.flatMap {
thing2 =>
thingToWaitFor3.map {
thing3 => // etc
}
}
}
当然,一旦定义了这些映射值(thing1
、thing2
和thing3
),您可以在任何时候对它们进行处理,而不仅仅是在最高或最低级别
使用Futures比只等待结果要好得多,特别是对于异步应用程序。如果您不是异步的,那么我想等待是可以的。我只是想给你另一个选择 正如您所指出的,问题在于您没有等待数据库的响应。我在您的回答中看到,您使用了wait——虽然这是一种有效的做法,但如果您希望代码是异步的,那么您应该真正避免使用wait。当你的应用程序正在等待响应时,它实际上不能做任何其他事情 解决这个问题的一个常见方法是使用。未来的好处在于,在其核心,你假设在某个时刻会有一个响应,并且可以在未来等待完成时继续计算其他东西。如果你想使用未来的价值,你可以在它里面映射。这假设一旦将来完成了,您将对结果做一些事情。使用Future的一般示例:
import scala.concurrent.Future
// assuming you have a method called callDatabase in another class called connector
val thingToWaitFor: Future[String] = ???
thingToWaitFor.map {
thing => // do something with this thing (thing is now of type String)
}
如果您需要等待多个期货,则需要在所有外部期货上使用Scala的flatMap函数,并且只在最内部期货上使用map:
import scala.concurrent.Future
val thingToWaitFor1: Future[String] = ???
val thingToWaitFor2: Future[String] = ???
val thingToWaitFor3: Future[String] = ???
thingToWaitFor1.flatMap {
thing1 =>
thingToWaitFor2.flatMap {
thing2 =>
thingToWaitFor3.map {
thing3 => // etc
}
}
}
当然,一旦定义了这些映射值(thing1
、thing2
和thing3
),您可以在任何时候对它们进行处理,而不仅仅是在最高或最低级别
使用Futures比只等待结果要好得多,特别是对于异步应用程序。如果您不是异步的,那么我想等待是可以的。我只是想给你另一个选择