我的应用程序中有2个线程:
爬网站并将数据插入MongoDB
检索已经爬取的网站并执行业务逻辑
为了检索已经爬取的网站,我使用以下查询语句:
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));
}
我运行这段代码几天,并注意到有时会进入
if (this.trackedEpisodes.containsKey())
语句的else
部分。对我来说很奇怪,unfetchedEpisodes
和trackedEpisodes
为什么不同步并且不包含相同的项呢?我开始调查此问题并注意到在我到达
"BOO!检测到奇怪的新对象"
的时间,document
迭代器包含了数据库中的项目,但不应该出现在unfetchedEpisodes
中,因为我没有执行新的数据库查询。我多次检查了将检索到的项目存储到
trackedEpisodes
的问题,并且总是将所有元素从unfetchedEpisodes
添加到trackedEpisodes
中,但是之后有时仍然会进入"BOO!检测到奇怪的新对象"
。我的问题:
为什么在执行查询后,
unfetchedEpisodes
会得到新的项?在执行
Collection#query()
后,MongoDB驱动程序是否可能修改unfetchedEpisodes
?也许我应该在执行MongoDB查询后使用某种
.close()
?
MongoDB:3.2.3,x64
MongoDB Java Driver:mongodb-driver-3.2.2,mongodb-driver-core-3.2.2,bson-3.2.2