我有一个子集的数据
具有登录日期等的用户,然后是位置集合。
我想让所有在特定日期范围内登录的用户,然后看看每个郊区有多少人这样做
现在,在SQL中,我将连接表,进行一些分组和计数。
但在mongo中,我不确定最好的方法是使用聚合函数还是使用map reduce功能。
{
"_id" : ObjectId("50174af210bb50b471000036"),
"state_code" : "ACT",
"suburb" : "Barton",
"postcode" : 221,
"loc" : [149.129623, -35.302345]
}
配置文件看起来像这个
{
"_id" : ObjectId("50176d9b539ba2903e000001"),
"created_at" : ISODate("2012-07-31T05:31:07.538Z"),
"gender" : "female",
"first_name" : "Marge",
"last_name" : "Simpson",
"location_id" : ObjectId("50174af210bb50b471000235"),
"s_location_name" : "Surry Hills (NSW)",
"updated_at" : ISODate("2012-10-18T23:29:54.979Z"),
"user_id" : ObjectId("50176c2510bb50a618000002")
}
并且用户有最后一次登录
{ "_id" : ObjectId("50176c2510bb50a618000002"),
"created_at" : ISODate("2012-07-31T03:09:47.363Z"),
"last_sign_in_at" : ISODate("2012-10-08T04:56:53.751Z"),
"updated_at" : ISODate("2012-10-30T03:52:33.976Z")
}
我想要的是
墨尔本X用户在日期范围内注册
所以SQL伪代码将是
select suburb, count(*)
from user
where last_login between x and y
group by suburb
您在这里犯了一个经典的错误,即为数据设计数据模型(就像为关系数据库设计数据模型一样),而不是为日期使用设计数据模型。就像MongoDB中的任何其他操作一样,Aggregation Framework或Map/Reduce都不能在多个集合上完成。
在这种情况下,我可能会合并配置文件和用户集合,它们似乎不太有用,无论如何都不能分开。其次,如果locations集合中的郊区是唯一的,就像它的_id一样,那么你应该让_id是郊区的值,而不是一些虚构的Object id。如果郊区+州代码是唯一的,则将其设为_id字段。在MongoDB中,_id字段可以有任何类型。如果_id是值,那么您的用户/配置文件集合可以使用location_id(重命名为location_suburb.e.)的值(希望只是郊区名称),然后您就有了一个可以分组的模式设计:
db.users.aggregate( { $group: { _id: location_suburb, count: { $sum: 1 } } } );
提醒一下:尽管MongoDB是无模式的,但这并不意味着你不需要设计你的模式。