我将文档插入到capped collection中,我这样写:
// получить документ с необходимыми полями
Document found = collection.find().first();
String getTitle = (String) found.get("title");
String getUrl = (String) found.get("url");
String getImg = (String) found.get("img");
String getPrice = (String) found.get("price");
// документ, который мне нужно получить в новом виде
Document doc = collection.find(new Document("title", getTitle)
.append("url", getUrl)
.append("img", getImg)
.append("price", getPrice)
.append("sent", true)).first();
// если документ не существует, я вставляю как новый
if (doc == null) {
collection.insertOne(new Document("title", getTitle)
.append("url", getUrl)
.append("img", getImg)
.append("price", getPrice)
.append("sent", true));
}
这称为覆盖文档。我正在插入带有额外字段的新文档,而不是没有一个字段的旧文档。也就是说,一个文档在集合的开头被删除,一个新的文档出现在集合的末尾。
插入新文档而不是旧文档的过程正常进行,直到抛出异常:
com.mongodb.MongoSocketReadException: Prematurely reached end of stream
at com.mongodb.connection.SocketStream.read(SocketStream.java:88)
at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:491)
at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:221)
at com.mongodb.connection.CommandHelper.receiveReply(CommandHelper.java:134)
at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:121)
at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32)
at com.mongodb.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:83)
at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:43)
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
at com.mongodb.connection.UsageTrackingInternalConnection.open(UsageTrackingInternalConnection.java:46)
at com.mongodb.connection.DefaultConnectionPool$PooledConnection.open(DefaultConnectionPool.java:381)
at com.mongodb.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:96)
at com.mongodb.connection.DefaultConnectionPool.get(DefaultConnectionPool.java:82)
at com.mongodb.connection.DefaultServer.getConnection(DefaultServer.java:72)
at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.getConnection(ClusterBinding.java:86)
at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:237)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:212)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:482)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:79)
at com.mongodb.Mongo.execute(Mongo.java:772)
at com.mongodb.Mongo$2.execute(Mongo.java:759)
at com.mongodb.FindIterableImpl$FindOperationIterable.first(FindIterableImpl.java:207)
at com.mongodb.FindIterableImpl.first(FindIterableImpl.java:148)
at project.Bot.onUpdateReceived(Bot.java:347)
我猜错误就在这条线上:
Document found = collection.find().first();
我尝试使用此代码段解决问题(我有一个免费的 Tier M0 集群):
List<ServerAddress> List = new ArrayList<>();
List.add(new ServerAddress("cluster0-shard-00-00-ox90k.mongodb.net", 27017));
List.add(new ServerAddress("cluster0-shard-00-01-ox90k.mongodb.net", 27017));
List.add(new ServerAddress("cluster0-shard-00-02-ox90k.mongodb.net", 27017));
char[] password = "mypassword".toCharArray();
List<MongoCredential> cred = new ArrayList<>();
cred.add(MongoCredential.createCredential("user", "db_feed", password));
MongoClientOptions optionsBuilder = MongoClientOptions.builder()
.readPreference(ReadPreference.primaryPreferred())
.requiredReplicaSetName("Cluster0-shard-0")
.maxConnectionIdleTime(60000)
.build();
MongoClient mongoClient = new MongoClient(List, cred, optionsBuilder);
但在这种情况下,我得到另一个例外:
com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primaryPreferred}. Client view of cluster state is {type=REPLICA_SET, servers=[{address=cluster0-shard-00-00-ox90k.mongodb.net:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Prematurely reached end of stream}}, {address=cluster0-shard-00-01-ox90k.mongodb.net:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Prematurely reached end of stream}}, {address=cluster0-shard-00-02-ox90k.mongodb.net:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Prematurely reached end of stream}}]
at com.mongodb.connection.BaseCluster.createTimeoutException(BaseCluster.java:369)
at com.mongodb.connection.BaseCluster.selectServer(BaseCluster.java:101)
at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:75)
at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:71)
at com.mongodb.binding.ClusterBinding.getReadConnectionSource(ClusterBinding.java:63)
at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:210)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:482)
at com.mongodb.operation.FindOperation.execute(FindOperation.java:79)
at com.mongodb.Mongo.execute(Mongo.java:772)
at com.mongodb.Mongo$2.execute(Mongo.java:759)
at com.mongodb.FindIterableImpl$FindOperationIterable.first(FindIterableImpl.java:207)
at com.mongodb.FindIterableImpl.first(FindIterableImpl.java:148)
at project.Bot.onUpdateReceived(Bot.java:347)
从这个异常发生的时间来看,这似乎是由于连接的行的格式,因为我在连接驱动程序版本 3.6 和更高版本时已经出现了这样的错误。(一切都依赖于+srv前缀,这不允许使用 3.6 及更高版本的新版本的驱动程序正常工作)。我注意到在其他语言中,比如 Python,他们通过+srv连接一个单独的. 我不知道如何在 Java 中实现它,因为 看起来像拐杖。
顺便说一句,当我连接 Java 3.4 驱动程序版本com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting时,它会自行消失:
MongoClientURI connectionString = new MongoClientURI("mongodb://admin1:mypassword@cluster0-shard-00-00-ox90k.mongodb.net:27017,cluster0-shard-00-01-ox90k.mongodb.net:27017,cluster0-shard-00-02-ox90k.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true");
MongoClient mongoClient = new MongoClient(connectionString);
我很想听听关于我的问题的意见,在此先感谢。
一个类似的问题已经在英文堆栈上被问过。


通过加入格式(使用
maxIdleTimeMS,ssl和选项authSource)解决了错误:或者,您可以手动输入凭据(使用 java 驱动程序
3.6+版本):admin是 Atlas 中定义用户的数据库;user是用户名;mypassword- 这是密码;