ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

java – 执行查询后修改MongoDB结果集

2019-07-02 10:48:15  阅读:279  来源: 互联网

标签:java mongodb synchronization


在我的应用程序中有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!奇怪的新对象检测到”的时间文件迭代器包含数据库中的项目但不应该在unfetchedEpisodes中,因为我没有执行新的查询数据库.

我检查了几次将检索到的项目存储到trackedEpisodes的问题,并且始终将来自unfetchedEpisodes的所有元素添加到trackedEpisodes,但在此之后我仍然会到达“BOO!检测到奇怪的新对象”.

我的问题:

>为什么unfetchedEpisodes在执行查询后获取新项?
>执行Collection#query()后,MongoDB驱动程序是否可以修改unfetchedEpisodes?
>从MongoDB执行查询后,我可能应该使用.close()吗?

使用的版本:

> MongoDB:3.2.3,x64
> MongoDB Java驱动程序:mongodb-driver-3.2.2,mongodb-driver-core-3.2.2,bson-3.2.2

解决方法:

当你在这里打电话时:

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

你实际上并没有收到所有的剧集.您正在获取指向匹配文档的数据库游标.

然后当你打电话:

for (Document document : unfetchedEpisodes){}

在与查询匹配的所有文档上创建迭代器.

当您再次调用它时,将为同一查询返回一个新游标,并且迭代现在匹配的所有文档.

如果集合之间发生了变化,结果将会有所不同.

如果你想确保unfetchedEpisodes的内容没有改变,那么你可以将一个选项拉到内存中并在内存中而不是在数据库上迭代它,例如,

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

标签:java,mongodb,synchronization
来源: https://codeday.me/bug/20190702/1355533.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有