MongoDB分析集合 - 查找X做过Y的用户

时间:2015-04-02 18:48:36

标签: mongodb

我在MongoDB集合中收集了大量event个文档。每个文档中的字段包括:

  • userId(数据库ID,如果用户已登录)
  • visitorId(Cookie id,始终存在)
  • eventType(用户刚刚完成的事件类型)

特别感兴趣的是一个eventType - “购买”类型。我要做的是运行一个基本上说:

的查询
  

获取执行特定活动的用户的所有购买活动的列表。

最初我的想法是简单地下载执行事件的所有用户的列表,然后将其用作大规模查询条件。然而,这感觉很难看,而且我想想对于更大的查询,它在内存方面会非常昂贵。

有更好/更聪明的方法吗?

2 个答案:

答案 0 :(得分:2)

我非常怀疑使用聚合框架会有什么好处。另外我不清楚你可以在一个查询中做你想做的事情(我认为这是不可能的)。另一方面,我相信你的出发方式是最好的。我会做什么:

你有你的收藏:

db.events.insert({userId: 1, event: 1})
db.events.insert({userId: 2, event: 1})
db.events.insert({userId: 3, event: 4})
db.events.insert({userId: 1, event: 4})
db.events.insert({userId: 3, event: 2})
db.events.insert({userId: 1, event: 3})
db.events.insert({userId: 3, event: 1})

获取完成某些活动的所有唯一身份用户:

var usersSet = {};
db.events.find({event: 1}, {userId: 1, _id:0}).forEach(function(el){
  return usersSet[el.userId] = 1;
});

注意,因为mongoshell没有正常的set数据类型(如果你使用js/node.js it finally has),我将它存储在对象中,稍后如果你的id是整数,它们将丢失它们的类型。这就是我之后用map(Number)翻译它们的原因。

拥有您的用户,您可以通过活动执行类似的操作。如果您需要拥有所有事件(并非我正在做的那么独特),只需将eventSet更改为eventArray并按下返回功能。

var eventsSet = {}    
db.events.find({
   userId: {$in: Object.keys(usersSet).map(Number)}
}, {
  event: 1, _id:0
}).forEach(function(el){
  return eventsSet[el.event] = 1;
});

Object.keys(eventsSet).map(Number)将包含所有唯一事件。

答案 1 :(得分:1)

我想说这种查询不适合mongodb。它可以通过不同的方式完成,但它们都没有为真正的大数据集提供良好的性能。

它的想法是你可能有另一个集合来保持用户及其事件的发生。

{
    userid : "_user_id",
    events : ["event_type1", "event_type2"]
}

你需要保持这个集合是最新的(即每个事件的upsert)

或者您可以保留事件计数以供将来使用,例如:

{
    userid : "_user_id",
    event_type_1 : 5,
    event_type_2 : 16,
    event_type_3 : 2,       
}

你可以查询存在和出现次数。对于第一个选项,您需要将新事件类型推送到特定用户的events数组,对于第二个选项,您将自动增加事件类型的出现。