草庐IT

java - MongoDB 结果集在执行查询后被修改

coder 2023-10-28 原文

在我的应用程序中有 2 个线程:

  1. 抓取网站并将数据插入 MongoDB

  2. 检索抓取的网站并执行业务逻辑

为了检索已抓取的网站,我使用以下查询:

Document query = new Document("fetchStatus", new Document("$lte", fetchStatusParam));
FindIterable<Document> unfetchedEpisodes = dbC_Episodes.find(query);

结果我得到了所有剧集,它是 fetchStatusParam小于或等于特定值。

下一步,我将结果集的项存储在 HashMap<String, TrackedEpisode> 中,这是一个对象属性,以便跟踪它们:

for (Document document : unfetchedEpisodes) {
    this.trackedEpisodes.put(document.get("_id").toString(), new TrackedEpisode(document));
}

然后我做一些业务逻辑,其中:

  • 修改unfetchedEpisodes结果集。

  • 不会trackedEpisodes 中移除任何对象.

到目前为止一切正常。
最后一步,我传递所有检索到的文档并将它们标记为已提取,以防止将来重复提取。

for (Document document : unfetchedEpisodes) {

    if (this.trackedEpisodes.containsKey(document.get("_id").toString())) {

        // prevent repeated fetching
        document.put("fetchStatus", FetchStatus.IN_PROCESS.getID());

        if (this.trackedEpisodes.get(document.get("_id").toString()).isExpired()) {
            document.put("isExpired", true);
            document.put("fetchStatus", FetchStatus.FETCHED.getID());
        }
    } else {
        System.out.println("BOO! Strange new object detected");
    }

    dbC_Episodes.updateOne(new Document("_id", document.get("_id")), new Document("$set", document));
}

我运行这段代码几天,注意到它有时会到达 elseif (this.trackedEpisodes.containsKey()) 的一部分陈述。这对我来说很奇怪,unfetchedEpisodes 怎么可能和 trackedEpisodes不同步且不包含相同的项目?

我开始查案,注意我到达的时间是"BOO! Strange new object detected" document迭代器包含数据库中但不应该在 unfetchedEpisodes 中的项目因为我没有对数据库执行新查询。

我检查了几次将检索到的项目存储到 trackedEpisodes 中的问题并且总是来自 unfetchedEpisodes 的所有元素已添加到 trackedEpisodes但在那之后有时我仍然会到达"BOO! Strange new object detected" .

我的问题:

  1. 为什么 unfetchedEpisodes执行查询后获取新项目?

  2. 有没有可能 unfetchedEpisodes将在执行 Collection#query() 后由 MongoDB 驱动程序修改?

  3. 也许我应该使用 .close()从 MongoDB 执行查询后?

使用的版本:

  • MongoDB:3.2.3,x64

  • MongoDB Java 驱动程序:mongodb-driver-3.2.2mongodb-driver-core-3.2.2bson-3.2.2

最佳答案

当你在这里调用find时:

FindIterable<Document> unfetchedEpisodes = dbC_Episodes.find(query);

您实际上并没有恢复所有剧集。您将获得一个指向匹配文档的数据库游标。

然后当你打电话时:

for (Document document : unfetchedEpisodes){}

在所有匹配查询的文档上创建一个迭代器。

当您第二次调用它时,将针对同一查询返回一个新游标,并遍历所有匹配now 的文档。

如果两者之间集合发生变化,结果将不同。

如果您想确保 unfetchedEpisodes 的内容不变,那么一种选择是您可以将整个结果集拉入内存并在内存中而不是在数据库中对其进行迭代,例如

ArrayList<Document> unfetchedEpisodes = dbC_Episodes.find(query).into(new ArrayList<Document>());

关于java - MongoDB 结果集在执行查询后被修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35535076/

有关java - MongoDB 结果集在执行查询后被修改的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  3. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  4. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  5. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  6. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  9. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐