Mongodb 存储和检索用户';喜爱的标签

Mongodb 存储和检索用户';喜爱的标签,mongodb,analytics,nosql,Mongodb,Analytics,Nosql,我正试图在我的电子商务网站上实施针对性营销的行为分析。基本思想如下(我假设使用MongoDB,但期待其他建议): 每个网站类别都有一个与之相关的标签列表 每个内容文章也有一个标签列表 每个用户在第一次访问时都有一个唯一的cookie ID分配给他/她 每次用户浏览类别或阅读文章,我们计划如下增加用户标签字典: db.tagviews.update( {_id: user_id}, {$inc: {'tags.foo': 1, 'tags.bar': 1, 'tags.baz':

我正试图在我的电子商务网站上实施针对性营销的行为分析。基本思想如下(我假设使用MongoDB,但期待其他建议):

  • 每个网站
    类别
    都有一个与之相关的
    标签列表
  • 每个内容
    文章
    也有一个
    标签列表
  • 每个
    用户在第一次访问时都有一个唯一的cookie ID分配给他/她
  • 每次用户浏览
    类别
    或阅读
    文章
    ,我们计划如下增加
    用户标签
    字典:

    db.tagviews.update(
        {_id: user_id},
        {$inc: {'tags.foo': 1, 'tags.bar': 1, 'tags.baz': 1}},
        true /* upsert */
    )
    
因此,如果我们想查看特定用户的兴趣,我们可以为他获取
tagviews
文档,并查看
标记
以查看哪些标记的视图最多

然而,我偶然发现了一件非常琐碎的事情——如何根据标记标准获取用户。例如,我们有价格诱人的Google Galaxy Nexus库存,并希望向对
[android、手机、小工具、谷歌]
最感兴趣的用户发送营销电子邮件

据我所知,我们必须在tagviews集合中的每个
标记。*
字段上创建索引,这当然是不可接受的。另一种可能的解决方案是在另一个维度中复制数据(增加标记用户组合而不是用户标记)。但syntetic测试在磁盘空间和灵活性方面看起来非常不乐观

您有什么建议可以根据标签标准有效地吸引最感兴趣的用户


谢谢

从您的示例中,我了解到您正在使用标记名作为标记视图集合中的键(又名字段)

不要这样做,这会让你在需要创建索引时陷入噩梦。而是将标记创建为标记视图中的嵌入文档

 tagviews{
      _id : 'xxxx',
      tags : [
        {
           name : "foo",
           count : 0
        },
        {
           name : "bar",
           count : 0
        },
        {
           name : "baz",
           count : 0
        }   
      ]
您可以通过标记名有效地索引此文档,以便在过滤器中使用它

db.tagviews.ensureIndex('tags.name',1)
您可以通过以下方式增加用户的特定标记视图

db.tagviews.update({_id : "userid" , "tags.name":'foo'},{$inc:{"tags.$.count":1}})
当你的用户偶然发现他的兴趣时

所以对于你真正的问题

如何根据标记条件获取用户。我们有谷歌 Galaxy Nexus以极具吸引力的价格上市,并希望 向对[android、手机、, 小工具,谷歌]

你可以像这样过滤它

 db.tagviews.find({'tags.name':{$in : ['android', 'phones','gadgets','google'] }})
这将检索对上述标签感兴趣的所有用户

甚至可以使用count来过滤最精确的数据

db.tagviews.find({'tags.name':{$in : ['android', 'phones','gadgets','google'] },'tags.count' : {$gt : 0 }})

希望这有助于

从您的示例中,我了解到您正在使用标记名作为标记视图集合中的键(又名字段)

不要这样做,这会让你在需要创建索引时陷入噩梦。而是将标记创建为标记视图中的嵌入文档

 tagviews{
      _id : 'xxxx',
      tags : [
        {
           name : "foo",
           count : 0
        },
        {
           name : "bar",
           count : 0
        },
        {
           name : "baz",
           count : 0
        }   
      ]
您可以通过标记名有效地索引此文档,以便在过滤器中使用它

db.tagviews.ensureIndex('tags.name',1)
您可以通过以下方式增加用户的特定标记视图

db.tagviews.update({_id : "userid" , "tags.name":'foo'},{$inc:{"tags.$.count":1}})
当你的用户偶然发现他的兴趣时

所以对于你真正的问题

如何根据标记条件获取用户。我们有谷歌 Galaxy Nexus以极具吸引力的价格上市,并希望 向对[android、手机、, 小工具,谷歌]

你可以像这样过滤它

 db.tagviews.find({'tags.name':{$in : ['android', 'phones','gadgets','google'] }})
这将检索对上述标签感兴趣的所有用户

甚至可以使用count来过滤最精确的数据

db.tagviews.find({'tags.name':{$in : ['android', 'phones','gadgets','google'] },'tags.count' : {$gt : 0 }})

希望这有帮助

谢谢,我有点错过了
$
接线员。唯一的缺点是,我必须为需要更新的每个标记发布更新(因为$matches只在第一次出现时才出现)。以标签为键,只需1次更新。是的,确实如此。使用[positional operator in update all matching embedded docs]时存在一个开放性问题。当这个问题解决后,您可以像使用
db.tagviews.update({u id:“userid”,“tags.name”:{$in:['foo','bar','baz']},{$inc:{“tags.$.count”:1})一样使用它
FYI,我做了一些测试并停止使用
tags.tagname:count
选项。虽然这对某些用例可能不好,但我使用稀疏索引对这些字段进行索引。标记计数将相当低(例如<10000),所以索引开销是可以的。主要原因是$-operator不支持对不存在的文档进行upsert,因此我必须在每个请求中仔细检查用户文档是否存在。谢谢,我有点错过了
$
操作符。唯一的缺点是我必须为需要更新的每个标记发布更新(因为$只匹配第一次出现)。使用标记作为键只需要1次更新。是的,确实如此。在更新所有匹配的嵌入文档时使用[Position operator]存在一个公开问题。当这个问题准备好后,您可以像
db.tagviews.update那样使用它({u-id:“userid”,“tags.name”:{$in:['foo','bar','baz']},{$inc tags.$.count:1})
FYI,我做了一些测试并停止使用
tags.tagname:count
选项。虽然这对某些用例可能不好,但我使用稀疏索引对这些字段进行索引。标记计数将相当低(例如<10000),所以索引开销是可以的。主要原因是$-operator不支持对不存在的文档进行upsert,因此我必须在每个请求上重新检查用户文档是否存在。