我有一个用户集合。每个用户都有评论。如果有新评论,我想跟踪一些特定用户(根据他们的ID)。
Tailable游标我猜是我需要的但我的主要问题是我想跟踪子文档而不是文档。
在python中跟踪文档的示例:
db = Connection().my_db
coll = db.my_collection
cursor = coll.find(tailable=True)
while cursor.alive:
try:
doc = cursor.next()
print doc
except StopIteration:
time.sleep(1)
一种解决方案是每x次运行间隔,看看评论的数量是否已更改。但是我没有发现间隔解决方案非常吸引人。 有没有更好的方法来跟踪更改?可能使用tailable游标。
PS:我在每个评论中都有一个comment_id
字段(这是一个ObjectID)。
小更新:
由于我有commect_id bson,我可以在每个用户中存储最大的(=最新的)。然后运行间隔比较bson,如果它仍然是最新的。我不介意不是一个精确的实时方法。即使是10分钟的延迟也没问题。但是现在我有70k用户和180k评论,但我担心这种方法的可扩展性。
答案 0 :(得分:0)
这将是我的解决方案。评估它是否符合您的要求 -
我假设数据结构如下
db.user.find().pretty()
{
"_id" : ObjectId("5335123d900f7849d5ea2530"),
"user_id" : 200,
"comments" : [
{
"comment_id" : 1,
"comment" : "hi",
"createDate" : ISODate("2012-01-01T00:00:00Z")
},
{
"comment_id" : 2,
"comment" : "bye",
"createDate" : ISODate("2013-01-01T00:00:00Z")
}
]
}
{
"_id" : ObjectId("5335123e900f7849d5ea2531"),
"user_id" : 201,
"comments" : [
{
"comment_id" : 3,
"comment" : "hi",
"createDate" : ISODate("2012-01-01T00:00:00Z")
},
{
"comment_id" : 4,
"comment" : "bye",
"createDate" : ISODate("2013-01-01T00:00:00Z")
}
]
}
我在文档中添加了createDate属性。添加索引如下 -
db.user.ensureIndex({"user_id":1,"comments.createDate":-1})
您可以使用查询搜索最新评论 -
db.user.find({"user_id":200,"comments.createDate":{$gt:ISODate('2012-12-31')}})
用于“大于”比较的时间将是最后检查时间。由于您使用的是索引,搜索速度会更快。您可以遵循在某个时间间隔内签入新注释的相同想法。
您也可以使用UTC时间戳,而不是ISODate。这样您就不必担心bson数据类型了。
请注意,在createDate上创建索引时,我指定了降序索引。
如果您在用户文档中有太多评论,在一段时间内,我建议您将评论移至其他集合。使用user_id作为注释文档中的一个属性。从长远来看,这将带来更好的表现。