RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 888786
Accepted
invzbl3
invzbl3
Asked:2020-10-04 04:14:17 +0000 UTC2020-10-04 04:14:17 +0000 UTC 2020-10-04 04:14:17 +0000 UTC

如何在 mongoDB 中使用 Java Driver 3.4+ 删除 Prematurely达到流异常结束?(插入时)

  • 772

我将文档插入到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);

我很想听听关于我的问题的意见,在此先感谢。


一个类似的问题已经在英文堆栈上被问过。

java
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    invzbl3
    2020-10-09T03:33:41Z2020-10-09T03:33:41Z

    通过加入格式(使用maxIdleTimeMS,ssl和选项authSource)解决了错误:

    maxIdleTimeMS - 连接在被丢弃和关闭之前可以在池中保持空闲的最大毫秒数。

    MongoClient mongoClient = MongoClients.create("mongodb://user: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&maxIdleTimeMS=5000");
    

    或者,您可以手动输入凭据(使用 java 驱动程序3.6+版本):

    admin是 Atlas 中定义用户的数据库;

    user是用户名;

    mypassword- 这是密码;

    MongoCredential credential = MongoCredential.createCredential("user", "admin", "mypassword".toCharArray());
            MongoClientSettings settings = MongoClientSettings.builder()
                    .credential(credential)
                    .retryWrites(true)
                    .applyToConnectionPoolSettings(builder ->
                            builder.maxConnectionIdleTime(5000, TimeUnit.MILLISECONDS))
                    .applyToSslSettings(builder -> builder.enabled(true))
                    .applyToClusterSettings(builder -> {
                        builder.hosts(Arrays.asList(
                                new ServerAddress("cluster0-shard-00-00-ox90k.mongodb.net", 27017),
                                new ServerAddress("cluster0-shard-00-01-ox90k.mongodb.net", 27017),
                                new ServerAddress("cluster0-shard-00-02-ox90k.mongodb.net", 27017)
                        ));
                        builder.requiredReplicaSetName("Cluster0-shard-0");
                    })
                    .build();
    
            MongoClient mongoClient = MongoClients.create(settings);
    
    1. 定义主机名时,指定副本集的所有主机名。这将解决 java.net.UnknownHostException。

    2. 您不能在连接中使用短 DNS 名称mongodb+srv。

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5