将子对象的id与另一个表匹配

时间:2015-04-21 03:57:48

标签: mongodb

我们将系统的一部分从MySQL转换为MongoDB,我们的结构思想是看起来像这样(子集):

广告

{
    _id: ObjectId(),
    campaign: {
        title: "Some Title",
        budget: 100,
        host: "example.com",
        ads: [{
            // Ad 1 here
        },{
            // Ad 2 here
        },{
            // Ad 3 here
        }]
    }
}

因此,此对象将包含一个campaign对象,其中包含以下信息:标题,预算,主机等。它还会包含ads个对象数组,其中包含广告系列中的每个广告。

统计

{
    ad: {
        campaignId: ObjectId(),
        adId: 1
    },
    // Other stuff
}

这将包含对Ads收藏集

中找到的广告的每次展示/点击的统计信息

由于上面集合中的每个广告都是一个数组,并且该集合中的记录只有一个_id,因此将统计信息与特定广告系列中的特定广告进行匹配的最佳方式是什么?

1 个答案:

答案 0 :(得分:3)

从第一眼看,我看不出将广告嵌入广告系列的原因。想想玛格丽特·阿斯特(Margaret Astor)等人的大规模全球活动 - 你可能会达到16MB的文件大小限制而没有嵌入的最轻微的优势。我会模仿完全不同的。

广告系列应包含与特定广告无关的所有内容:

{
  _id: new ObjectId(),
  customer: "SomeCustomerReference"
}

个别广告(我假设横幅广告)应该是这样的:

{
  campaign: Ref("SomeCampaignId"),
  someInfo: "Awesome product from Acme!"
  ...
}

所以,我们已经清理了这个。现在,来统计。首先,您可以为上述添加添加一个计数器,并在此计数器上使用$inc operator。但是,这不是很精细。所以我会为每次展示使用第三个集合

{
  _id: ObjectId(),
  ad: Ref("Ad"),
  impression: new ISODate(),
  location: "http://awesome.cool/",
}

现在,点击广告时您需要做的就是更新展示次数:

db.impressions.update(
  { _id: "SomeIdDerivedFromReferralCode" },
  { $set: { clicked: new ISODate() } }
)

最后但同样重要的是,您可以使用aggregation framework和其他一些方法从该简单结构中获取大量信息。一个简单的示例是计算广告“foo”的点击展示次数:

db.impressions.find({ ad:"foo", clicked:{ $exists: true } } ).count()

您可以确定一天中的哪个时间和一周中的哪一天发生了最多/最少的点击次数,去年12月24日点击了多少广告等等。

由于我们没有使用嵌入式文档或数组,因此该模型可以很好地扩展。没有机会触及16MB文档大小限制,因为成员添加到大型数组中而没有频繁的文档迁移。