社交活动源 - MongoDB中每用户上限收集的最佳方法?

时间:2015-03-31 00:46:31

标签: mongodb capped-collections activity-streams

我正在开发一个非常类似于10Gen社交网站项目的社交活动供稿系统,该项目已经在生产中运行了几年。我有一个新的用例,其中我需要存储每个用户的按时间顺序排列的活动列表,其中活动列表应该:

  1. 仅包含最近插入的N个项目
  2. 不插入语义等效项目的重复项
  3. 允许分页结果。
  4. 到目前为止,我已经提出了两种方法来解决这个问题,但两者似乎都有一些令人不安的限制。

    第一种方法(与我的其他集合紧密匹配)是拥有一个集合,其中包含每个活动的一个文档,由用户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

0 个答案:

没有答案