1

根据 mongoDB 文档,不建议为大型数组创建多键索引,那么替代选项是什么?

我想在他们的一个联系人也开始使用该应用程序时通知我的应用程序用户,因此我必须上传和管理每个用户的联系人列表。我们正在使用带有副本集的 mongoDB 和两台辅助机器。mongo 可以处理具有数百个值的数组的多键索引吗?数十万用户的数百个联系人可能很难管理。

多键解决方案如下所示:

{
  customerId: "id1",
  contacts: ["aaa", "aab", "aac", .... "zzz"]
}

指数:createIndex({ contacts: 1 })

另一种解决方案是将每个联系人保存在自己的文档中,并保存与他相关的所有应用用户:

{
  phone: "aaa",
  contacts: ["id1", "id2", "id3"]
},
{
  phone: "aab",
  contacts: ["id1"]
},
{
  phone: "aac",
  contacts: ["id1"]
},
......
{
  phone: "zzz",
  contacts: ["id1"]
}
index: createIndex( { phone: 1 } )

两者在上传联系人列表时的写入性能都很差:
第一个是计算巨大的索引,第二个是并发更新大量文档。
有更好的方法吗?
我正在使用带有两台辅助机器的副本集,分片键有帮助吗?

谢谢

4

1 回答 1

0

为了索引包含数组值的字段,MongoDB 为数组中的每个元素创建一个索引键。这些多键索引支持 对数组字段的高效查询。所以如果我是你,我的数据模型会是这样的:

{
    customerId: "id1",
    contacts: ["_idx", "_idy", "_idw", .... "_idz"]
}

然后在联系人上创建索引。MongoDB 默认在 id 上创建索引。因此,您必须为非应用用户创建新文档,只需尝试添加一个字段,例如“app_user”:true/false。

对于索引性能,您可以让它在后台构建而没有任何问题,对于副本集,这就是它的完成方式。

对于分片,它对您没有帮助,因为您甚至无法对任何内容进行分片,因为您的集群中有一个主节点。分片至少需要 2 组主要的 Mongo 实例,因此在您的情况下,您可以添加第四台服务器,然后拥有两个副本集,一个主副本集和一个辅助副本集,然后将它们分片,并将您的系统转换为 2 个复制分片。

一旦实现了这一点,它显然会平衡 2 个分片之间的负载,尽管 MongoDB 需要处理的一百个文档并不多。

另一方面,如果您要进行分片,则需要更多设置,如果您使用的是 Mongodb 3.4 或更高版本,则用于配置服务器。

于 2018-03-18T00:39:55.373 回答