我如何实时监听MongoDB上的更改?

时间:2018-11-15 19:13:27

标签: python mongodb

我有一个数据库,我正在其中发送一些数据。同时,我正在运行Python脚本,我希望此脚本在添加后立即在控制台上向MongoDB数据库发送最后一个条目。

几天来我一直在寻找解决方案,却找不到任何东西。

我进行了一些研究,发现: a)尾部游标,但是唯一的问题是我的数据库没有设置上限,并且由于我将每隔5秒钟放置一次数据,因此我担心设置上限的数据库不足以满足我的需求,因为达到最大大小时将开始覆盖最旧的记录b)change_streams,但是我的数据库不是副本集,对此我还很陌生,所以我仍然必须学习更多高级主题,例如RS。

有什么建议吗?

这是我到目前为止所得到的:

from pymongo import MongoClient
import pymongo
import time
import random
from pprint import pprint

#Step 1: Connect to MongoDB - Note: Change connection string as needed
client = MongoClient(port=27017)


db = client.one

mycol = client["coll"]


highest_previous_primary_key = 1

while True:
    cursor = db.mycol.find()
    for document in cursor:

        # get the current primary key, and if it's greater than the previous one
        # we print the results and increment the variable to that value
        current_primary_key = document['num']
        if current_primary_key > highest_previous_primary_key:
            print(document['num'])
            highest_previous_primary_key = current_primary_key

但是问题在于,它将在第4条记录之后停止打印,而且我不知道这是否是我的数据库何时拥有大量数据的最佳解决方案。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

  

b)change_streams,但是我的数据库不是副本集,对此我还很陌生,所以我仍然必须学习更高级的主题,例如RS

Replica sets提供冗余和高可用性,并且是所有生产MongoDB部署的基础。话虽如此,对于测试和/或部署,您可以仅使用一个成员来部署副本集。对于本地测试示例:

mongod --dbpath /path/data/test --replSet test

本地测试服务器启动后,请与mongo shell连接以执行rs.initiate()

mongo
> rs.initiate()

查看相关的Deploy a replica set for testing and deployment

try:
    # Only catch insert operations
    with client.watch([{'$match': {'operationType': 'insert'}}]) as stream:
        for insert_change in stream:
            print(insert_change)
except pymongo.errors.PyMongoError:
    # The ChangeStream encountered an unrecoverable error or the
    # resume attempt failed to recreate the cursor.
    logging.error('...')

另请参阅pymongo.mongo_client.MongoClient.watch()

答案 1 :(得分:0)

这有点晚了,但您也可以使用以下方法在没有副本集的情况下这样做: highest_previous_primary_key = 0

虽然为真: 游标 = collection.find() 对于光标中的文档:

    # get the current primary key, and if it's greater than the previous one
    # we print the results and increment the variable to that value
    current_primary_key = collection.count()
    if current_primary_key > highest_previous_primary_key:
        curs = collection.find()
        curs[highest_previous_primary_key:]
        for i in curs:
            print(i)
        highest_previous_primary_key = current_primary_key