我正在开发一个非常类似于10Gen社交网站项目的社交活动供稿系统,该项目已经在生产中运行了几年。我有一个新的用例,其中我需要存储每个用户的按时间顺序排列的活动列表,其中活动列表应该:
到目前为止,我已经提出了两种方法来解决这个问题,但两者似乎都有一些令人不安的限制。
第一种方法(与我的其他集合紧密匹配)是拥有一个集合,其中包含每个活动的一个文档,由用户ID索引。例如:
{
"owner": {
"type": "user",
"id" : "1234"
},
"activity": {
"published": "2013-09-27T17:08:26+00:00",
"actor": {
"type": "elastic-search-node",
"id": "2"
},
"verb": "recommend",
"object": {
"type": "review",
"id": "1093773"
}
"uuid": "6d70eaa4-0766-4949-971d-98740cb9eca1"
}
}
每次我收到给定用户的新活动时,我都会插入一个上面的文档,其中包含相同的'owner'子句,但是不同的'activity'子句。但是,我不确定处理插入的最有效方法。鉴于上述标准,一种伪代码方法将是:
results = collection.update(
{
'owner.id':'1234',
'activity.verb':'recommend',
'activity.object.type':'review',
'activity.object.id':'1093773'
},
the_activity,
upsert:true)
# count documents for owner.id = 1234
# if count > max_documents, delete oldest document
这种方法的问题在于它最多可能需要3个数据库操作才能完成插入和修剪。但是,使用'upsert'可以防止重复,我们可以使用生成的ObjectID进行时间查询和分页。
我看过的另一种方法类似于社交网站中的FanoutOnWriteSizedBuckets方法。在这种情况下,活动列表作为子文档存储在max-size数组中,由用户标识索引。例如:
{
"owner" : {"type":"user", "id":"1234"},
"feed" : [
{"_id" : ObjectId("...da7"), "activity" : ...},
{"_id" : ObjectId("...dc1"), "activity" : ...},
{"_id" : ObjectId("...dd2"), "activity" : ...}
]
}
在这种情况下,查询也相当简单,但再次,插入是有问题的。我已经看过使用各种技术和$ update,$ push,$ addToSet,$ ne,$ each等的组合,但似乎没有一个能够以更有效的方式完成防止重复插入和修剪操作。上方。
有人可以提出解决此用例的方法吗?
谢谢!
(x-posted发布到mongodb-user Google Group) 已解决:https://groups.google.com/forum/#!topic/mongodb-user/K8n7Gf1nv3Q