我正试图编写一个跟踪脚本,但我在弄清楚数据库应该如何工作方面遇到了困难.

在MySQL中,我会创建一个类似于

User:
   username_name: string

Campaign:
   title: string
   description: string
   link: string

UserCampaign:
   user_id: integer
   camp_id: integer

Click:
   os: text
   referer: text
   camp_id: integer
   user_id: integer

我需要能够:

  • 查看每次点击的信息,如IP、Referer、OS等
  • 看看有多少次点击来自X IP、X Referer和X OS
  • 将每次单击与用户和活动关联

如果我按照

User {
     Campaigns: [
         {
           Clicks: []
         }
     ]
}

我遇到了两个问题:

  • 它会 for each 用户创建一个新的活动对象,这是一个问题,因为如果我需要更新我的活动,我需要 for each 用户更新对象
  • 我希望Clicks数组包含大量数据,我觉得将其作为用户对象的一部分会使查询速度非常慢

推荐答案

好吧,我想你需要把它分成基本的"种类".

您有两个"实体"样式的对象:

  • User
  • 运动

您有一个"映射"样式的对象:

  • User运动

您有一个"事务"样式的对象:

  • Click

Step 1: entity

让我们从简单的开始:User&;运动.这确实是两个独立的物体,任何一个都不依赖于另一个物体的存在.两者之间也没有隐含的继承权:用户不属于活动,活动也不属于用户.

当您有两个这样的顶级对象时,它们通常会获得自己的Collection .所以你需要Users个系列和Camapaigns个系列.

Step 2: mapping

User运动目前用于表示N-to-M映射.一般来说,当你有一个N对1的映射时,你可以把N放在1的内部.然而,在N-to-M映射中,您通常必须" Select 一方".

理论上,您可以执行以下操作之一:

  1. 在每个User中列出运动 ID
  2. 在每个运动中列出Users ID

就我个人而言,我会做#1.你可能会有更多的用户参与活动,你可能会想把数组放在更短的地方.

Step 3: transactional

点击是一种完全不同的野兽.在客观方面,你可以这样想:Clicks"属于"a UserClicks"属于"a 运动.所以,从理论上讲,你可以只存储这些对象中任何一个的点击.很容易认为点击属于under个用户或活动.

但如果你真的深入研究,以上的简化确实是有缺陷的.在你的系统中,Clicks实际上是一个中心对象.事实上,你甚至可以说;活动实际上只是与点击"相关".

看看你正在问的问题/疑问.所有这些问题实际上都围绕着点击.Users & 运动s are not the central object in your data, Clicks are.

此外,点击将成为系统中最丰富的数据.你将获得比其他任何东西都多的点击次数.

在为这样的数据设计模式时,这是最大的障碍.有时,当"父"对象不是最重要的东西时,你需要推开它们.想象一下建立一个简单的Electron 商务系统.很明显,orders将"属于"users,但orders对系统来说是如此重要,它将成为一个"顶级"对象.

Wrapping it up

您可能需要三个系列:

  1. User -> has list of campaign._id
  2. 运动
  3. Clicks -> contains user._id, campaign._id

这应该满足您的所有查询需求:

查看每次点击的信息,如IP、Referer、OS等

db.clicks.find()

看看有多少次点击来自X IP、X Referer和X OS

db.clicks.group()或跑Map-Reduce.

将每次单击与用户和活动关联

db.clicks.find({user_id : blah})还可以将点击ID推送到用户和活动中(如果有意义的话).

请注意,如果你有很多点击,你真的需要分析你运行最多的查询.你不能对每个字段都建立索引,所以你通常需要运行Map Reduces来"汇总"这些查询的数据.

Mongodb相关问答推荐

在MogoDB中按时间间隔分组、统计文档和获取间隔时间

Golang mongodb聚合错误:管道阶段规范对象必须包含一个字段

mongo如何通过聚合加载嵌套文档

查询有关 Go 项目中对象数组的 MongoDb 集合

如何将交易列表变成 token 数量的对象?

将 MongoDB 转移到另一台服务器?

如何在 mongodb 中设置整数的默认值?

根据 Month 删除 mongodb 中的旧记录

如何使用 C# MongoDB 驱动程序检索字段子集?

MongoDB获取聚合查询的executionStats

mongodb上不区分大小写的查询

Docker 内部的 Mongo 身份验证

使用 brew upgrade Mongo update from 3.4 to 4.0 报错:在try 升级到 4.0 之前,数据文件需要完全升级到 3.6 版

$elemMatch 的 MongoDB 索引

mongodb无法启动

如何确保基于特定字段的数组中的唯一项 - mongoDB?

如何为 node.js 中的 MongoDB 索引指定 javascript 对象中的属性顺序?

带有索引字段的 MongoDB 正则表达式

MongoDb - 利用多 CPU 服务器进行写入繁重的应用程序

将日期从毫秒转换为 ISODate 对象