1

我目前正在 MongoDB 中开展一个项目,我想从数据库中随机抽取新产品的样本。但我的问题不是 MongoDB 特定的,我认为这是一个一般的数据库问题。

场景:

假设我们有一个产品集合(或表格)。我们还有一个用户集合(或表)。每次用户登录时,他们都会看到 10 个产品。这些产品是从集合/表中随机选择的。很简单,但要注意的是,每次用户登录时,都必须向他们展示 10 种他们以前从未见过的产品。我能想到的解决这个问题的两种明显方法是:

  1. 每个用户都从他们自己的所有产品的私人列表开始。每次他们获得其中一种产品时,该产品都会从他们的私人列表中删除。结果是下一次从这个先前修剪的列表中选择产品时,它已经只包含新项目。

  2. 每个用户都有一个以前查看过的产品的私人列表。当用户登录时,他们从主列表中随机选择 10 个产品,将每个产品的 id 与他们之前查看过的产品列表进行比较,如果该项目出现在之前查看过的列表中,应用程序会丢弃这个选择一个新的, 并迭代直到有 10 个新项目,然后将其添加到先前查看的列表中以供下次使用。

#1的问题是它似乎是一种巨大的浪费。您基本上会为 n 个用户复制列表数据。此外,向系统删除/添加新项目将是一场噩梦,因为它必须遍历所有用户。#2 似乎更可取,但它也有问题。为了保证 10 个新产品,您最终可能会对数据库进行大量额外和不必要的调用。随着用户使用的产品越来越多,可供选择的新产品越来越少,因此不得不扔掉一个并从数据库中获取新产品的机会大大增加。

有替代解决方案吗?我首先关心的是性能。我将放弃磁盘空间以优化性能。

4

3 回答 3

0

这样做怎么样:创建一个集合prodUser,其中只有产品的 ID 和客户 ID 列表(谁看过这些产品)。

{
  prodID : 1,
  userID : []
}

当客户登录时,您会发现尚未分配给该用户的 10 个 prodID

db.prodUser.find({
  userID : {
    $nin : [yourUser]
  }
})

(由于某种原因 $not 不起作用:-(。我没有时间弄清楚为什么。如果你愿意 - 请告诉我。)。在向这个人展示他的产品后 - 你可以更新他的 prodUser 集合。为了减轻mongos 无法找到随机元素 - 您可以随机插入元素,然后只找到前 10 个。

一切都应该运行得非常快。

于 2012-11-22T02:51:48.620 回答
0

如果你不关心 id 的序列有多随机,你可以这样做:

创建一个仅包含产品 ID 和顺序整数代理键列的随机表。在第一次登录时从列表中的随机点开始每个客户,然后循环浏览按该键排序的列表。如果您到达终点,请从顶部重新开始。

客户记录将包含他们看到的最后一个产品的单个值(随机列表中的代理项,而不是实际 id)。然后,您将在登录时提取接下来的十个并对客户进行一次更新。当然,它不会真的是随机的。但是这种表种子策略是许多更简单的伪随机数生成器的工作原理。

我看到的唯一问题是您的产品列表的增长速度是否比您的用户登录的速度更快。那么他们将永远看不到列表中出现在他们开始之前的部分。即便如此,拥有大量产品和非常活跃的用户,这应该比存储他们看到的所有内容要好得多。因此,如果产品以一组伪随机序列出现并不重要,那么这可能非常适合您。

编辑:

如果你也存储了他们开始的第一条记录,你仍然可以生成所有看到的东西的列表。这将是该值和上次查看之间的所有内容。

于 2012-11-21T18:18:06.077 回答
0

这两种方式完全浪费了主内存和辅助内存。您想展示 2 件从未见过的产品,但这是必须的吗?如果您有很多产品,随机 10 个产品很有可能是独一无二的。

3. 您可以列出 10 个随机产品,尽管不像 MySQL 中那么简单,但仍然没有 1 和 2 复杂。

于 2012-11-21T16:54:05.163 回答