在Mongo中按时间建模位置数据

时间:2015-01-31 16:56:58

标签: mongodb data-modeling

我真的很想如何为一个集合或一些集合建模。

我正在存储位置数据。

非常频繁地为多个用户提供位置数据。 每个用户都可以分配到多个任务。

用户模型(当前)

{
  _id: 123,
  name: "bob",
  email: "bob@gmail.com",
  address: "...."
}

任务模型

{
  _id: 456,
  name: "task 1",
  userIds: [123, ...] // multiple users per task
}

{
  _id: 789,
  name: "task 2",
  userIds: [123, ...] // user can be in multiple tasks (ie bob)
}

当用户提交我想要存储在mongo中的位置时。它将加上时间戳。

我不(如果可能)想要根据特定的“任务”存储用户位置。这是因为我的用户可能忘记从任务1切换到任务2(比如午餐后),如果我将每个任务的用户位置存储,如果他忘记切换,他就不会出现在任务2中。我意识到这将要求我为具有位置的用户“加入”taskIds或在每个位置文档中存储用户taskIds。

我的查询将过滤给定任务中每个用户的最后N个位置(按照最新的时间排序)。 IE浏览器。对于任务1中的所有用户,请在最后10个位置给我。

我试图建模:

简单的地理位置集合,每个位置一个文档

{userId:123,timestamp:{// time},location:{// geo}}

这是一个非常简单的模型(userId和timestamp上的索引)。然而,基于任务的查询变得困难。为此,我首先需要找到该任务中的所有用户,然后执行另一个查询以查找具有这些用户ID的所有位置。此模型中也不可能为用户获取最后10个位置。我可以使用聚合框架按用户分组,但是使用该框架我必须在组之前进行限制。意思是限制所有位置而不管用户说什么10.这将给我前10个排序位置,而不是每个用户的前10个排序位置。

我可以为每个位置条目添加用户所属的所有任务。但是,每当用户被添加到新任务时,我都必须更新许多位置条目。即使这样,我仍然无法使用此模型为每个用户获得N个位置

这么糟糕的模特吧:/

为每个用户分组位置(数组)

我还试图为每个用户提供一个文档,该文档中包含用户所属的任务列表(当用户被添加到任务时需要更新到doc。还要保留该用户的位置列表。

用户位置型号:

{
  userId: 123,
  teamIds: [456, 789], // all tasks user is a part of
  locations: [{loc1}, {loc2}, .... {locN}] // sorted by time
}

这更接近我的查询方式。由于每个文档用于单个用户分组,因此每个文档都是自然的。我可以查询属于团队456的所有用户,以及拼接数组以获得每个文档的N个位置。

然而,这有一个很大的问题。必须限制位置数组,否则我将遇到文档大小限制。

每个用户的组位置(数组),每天一个文档

我可以使用上述模型,但为了避免文档大小限制,我可以将每个用户文档的位置数限制为一天。每个用户每天IE一个doc。

{
  userId: 123,
  timestamp: // day timestamp
  taskIds: [456, 789], // all tasks user is a part of
  locations: [{loc1}, {loc2}, .... {locN}] // sorted by time
}

问题在于,每次在任务中添加/删除用户时,我都必须更新大量文档,添加/删除该任务。

真的试图解决这两个问题:

  1. 存储/查询位置,以便我可以按用户分组,并限制每个用户的位置数量为N个位置。
  2. 在找到这些位置时,请避免加入用户团队ID。
  3. 最后我知道在这一点上可能会有建议不使用mongo来建模这些数据。虽然我可能在这一点上倾向于同意:),但我不能随意切换我的数据库。

    仍然希望可能有一个“可行的”解决方案来模拟这种类型的数据,并且仍然具有良好的查询性能,而不会在每个插入/查询上花费太多工作(时间/性能)。

1 个答案:

答案 0 :(得分:0)

我仍然模糊地确定了位置和任务之间的关系,我认为,以及你的整体目标是什么,但是如果你有用户分配到任务,那么用户访问各个位置,你想找到作为特定任务的一部分,给定用户(或所有用户)访问的过去N位置,为什么不使文档代表特定位置上特定任务的特定用户:

{
    "user_id" : 0
    "task_id" : 99,
    "location" : "Switzerland"
    "time" : ISODate("2015-02-04T20:34:30.942Z")
}

您对单个任务中单个用户的最后10个位置的查询是

db.test.find({ "user_id" : user_id, "task_id" : task_id }).sort({ "time" : -1 }).limit(10)

这有用吗?如果没有,您能否清楚地解释哪些操作或要求与此结构不兼容?从你的问题中理解你的要求是非常困难的,所以这个尝试的答案可能会有助于更好的解释,一旦我更好地理解你的用例,我就可以用更有用的东西来编辑答案。