gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 09:14:09 28 4
gpt4 key购买 nike

在我的应用程序中有 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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com