MongoDB:如何将文档中另一个字段(不同于 _id)设置为 MongoDB 文档的 ID?

15
例如,如果我想将用户名作为我的mongo文档的唯一标识而不是使用默认的"_id",该怎么办呢?
我希望使用mongo.exe控制台实现这一目标。

2
如果用户名可能会更改,并且它们在其他文档中使用,我建议您不要将它们作为主键(_id),因为您需要更新所有指向新用户名的位置(并且由于MongoDB中没有事务,您将面临时间问题)。 - WiredPrairie
3个回答

20

MongoDB要求使用 _id 属性作为唯一的主键,并自动对其进行索引。

你有两个选项:

  1. 使用 _id 属性并将其设置为用户名。
  2. 创建一个用户名属性,然后在该新属性上添加索引。你仍然会有 _id,但可以使用用户名进行查询。

1
我知道,可以有这样的记录,比如{username:“John”,age:12},我的意思是没有_id。怎么做? - Andrei
2
你为什么想要移除 _id? - cirrus
3
当您定义用户名索引时,可以要求它是唯一的,如果这是您关心的问题。_id很小并且有用。只需将其保持原样,并在更好地理解Mongodb之前忽略它。 - Leopd
3
您可以使用投影 {_id: false} 来从查询结果中排除 _id 字段。 - tuned

1

_id 在复制中非常重要。您可以创建一个没有 _id 索引的集合,但是您永远无法复制数据库。 复制需要每个集合上的 _id 索引。


0
我知道,可能会有这样的记录,比如{username: "John", age: 12},我的意思是,没有 _id。怎么做到这一点呢?
我不确定为什么 @Serges 的回答不够清楚,但再次强调,是没有办法的。从技术上讲,在某些版本的MongoDB中,你仍然可以在固定集合中删除 _id,但除此之外就不行了。
另外,我对你使用的 username 有些担忧,因为它可能不适合像分片这样的活动,并且可能在集群等地方产生高活动的“热点”。由于我不处在你的位置,无法了解你的数据,所以这只是理论推测,但最好要考虑这些因素。

谢谢回答,但我只是想知道,这是如何可能的。让我提供更多细节。我正在使用.NET驱动程序,我可以编写以下代码:class User { [BsonId] public string Username { get; set; } public string Password { get; set; } }当我将这样的类对象放入mongodb中时,我得到的对象没有_id,并且我很好奇驱动程序如何解释这个对象。操作看起来像什么? - Andrei
@AndreiMikhalevich 等等,“当我将这样的类对象放入mongodb时,我得到的是没有_id的对象”,你是什么意思?你是说你正在保存一个带有_id的对象,但在数据库中它没有_id吗?这应该是不可能的。 - Sammaye
@AndreiMikhalevich:如果你插入一个没有_id的对象,C#驱动程序会自动生成一个。 _id是MongoDB文档必需的主键;您可以选择使用自己的标识符或使用默认的ObjectID - Stennie
@Sammaye:选择_id字段与你选择的分片键无关,分片键可以包括一个或多个字段。_id字段确实是不可变的(一旦设置就不能更改),但如果应用程序不允许用户更改其名称,则用户名可能是可以的。如果需要更改_id,还可以使用新的_id复制+重新插入文档(但需要额外的工作来更新对原始_id的任何引用)。 - Stennie
@Stennie,我对将用户名作为文档的_id的建议感到担忧,因为大多数分片都是基于_id或类似的东西,这只是我表达的一个关注点。 - Sammaye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接