我可以使用 String 作为 mongodb 文档的 ID 类型吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11090446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 12:42:35  来源:igfitidea点击:

Can I use String as ID type for mongodb document?

mongodbkeymorphia

提问by Gelin Luo

I am using java/morphia to deal with mongodb. The default ObjectId is not very convenient to use from Java layer. I would like to make it a String type while keep the key generation process using ObjectId, say _id = new ObjectId.toString().

我正在使用 java/morphia 来处理 mongodb。从 Java 层使用默认的 ObjectId 不是很方便。我想使其成为 String 类型,同时使用 ObjectId 保持密钥生成过程,例如_id = new ObjectId.toString()

I want to know if there is any side effects doing it this way? For example, will it impact the database performance or causing key conflicts in any means? Will it affect the sharding environment ...

我想知道这样做是否有任何副作用?例如,它是否会以任何方式影响数据库性能或导致密钥冲突?会不会影响分片环境...

回答by Sergio Tulentsev

You can use any type of value for an _idfield (except for Arrays). If you choose not to use ObjectId, you'll have to somehow guarantee uniqueness of values (casting ObjectId to string will do). If you try to insert duplicate key, error will occur and you'll have to deal with it.

您可以对_id字段使用任何类型的值(数组除外)。如果您选择不使用 ObjectId,则必须以某种方式保证值的唯一性(将 ObjectId 转换为字符串即可)。如果您尝试插入重复键,则会发生错误并且您必须处理它。

I'm not sure what effect will it have on sharded cluster when you attempt to insert two documents with the same _id to different shards. I suspect that it will let you insert, but this will bite you later. (I'll have to test this).

当您尝试将具有相同 _id 的两个文档插入不同的分片时,我不确定它会对分片集群产生什么影响。我怀疑它会让你插入,但这会在以后咬你。(我将不得不对此进行测试)。

That said, you should have no troubles with _id = (new ObjectId).toString().

也就是说,你应该没有问题_id = (new ObjectId).toString()

回答by Destino

I actually did the same thing because I was having some problem converting the ObjectId to JSON.

我实际上做了同样的事情,因为我在将 ObjectId 转换为 JSON 时遇到了一些问题。

I then did something like

然后我做了类似的事情

@Id
private String id;
public String getId() {
    return id();
}
public void setId(String id) {
    this.id = id;
}

And everything worked fine untill I decided to update a previously inserted document, when i got the object by Id sent it to the page via JSON and receive the same updated object also by JSON post and then used the save function from the Datastore, instead of updating the previous data it inserted a new document instead of updating the one that was already.

一切正常,直到我决定更新以前插入的文档,当我通过 Id 获取对象时,通过 JSON 将其发送到页面并通过 JSON 帖子接收相同的更新对象,然后使用数据存储中的保存功能,而不是更新以前的数据它插入了一个新文档,而不是更新已经存在的文档。

Even worst the new document had the same ID than the previously inserted one, something i thought was impossible.

更糟糕的是,新文档的 ID 与之前插入的 ID 相同,我认为这是不可能的。

Anyway i setted the private object as an ObjectID and just left the get set as string and then it worked as expected, not sure that helps in your case thought.

无论如何,我将私有对象设置为 ObjectID,然后将 get 设置为字符串,然后它按预期工作,不确定这对您的情况有帮助。

@Id
private ObjectId id;
public String getId() {
    return id.toString();
}
public void setId(String id) {
    this.id = new ObjectId(id);
}

回答by Dan H

Yes, you can use a string as your _id.

是的,您可以使用字符串作为 _id。

I'd recommend it only if you have some value (in the document) that naturally is a good unique key. I used this design in one collection where there was a string geo-tag, of the form "xxxxyyyy"; this unique-per-document field was going to HAVE to be in the document andI had to build an index on it... so why not use it as a key? (This avoided one extra key-value pair, AND avoided a second index on the collection, since MondoDB naturally builds an index on "_id". Given the size of the collection, both of these added up to some serious space savings.)

只有当你有一些价值(在文档中)自然是一个很好的唯一键时,我才会推荐它。我在一个系列中使用了这种设计,其中有一个字符串地理标签,形式为“xxxxyyyy”;这个每个文档唯一的字段必须在文档中我必须在它上面建立一个索引……那么为什么不把它用作键呢?(这避免了一个额外的键值对,并且避免了集合上的第二个索引,因为 MondoDB 自然会在“_id”上构建一个索引。考虑到集合的大小,这两个加起来可以节省一些空间。)

However, from the tone of your question ("ObjectIDs are not very convenient"), if the only reason you want to use a string is you don't want to be bothered with figuring out how to neatly manage ObjectIDs... I'd suggest it is worth your time to get your head around them. I'm sure they are no trouble... once you've figured out your trouble with them.

但是,从您的问题的语气(“ObjectIDs 不是很方便”)来看,如果您想使用字符串的唯一原因是您不想为弄清楚如何巧妙地管理 ObjectIDs 而烦恼......我' d 建议花时间了解它们是值得的。我敢肯定他们不会有问题……一旦你弄清楚了他们的问题。

Otherwise: what is your options? Will you concoct string IDs EVERY TIME you use a MongoDB in the future?

否则:你有什么选择?以后每次使用 MongoDB 时都会编造字符串 ID 吗?

回答by Tony Sepia

I would like to add that it is not always a good idea to use the automatically generated BSON ObjectID as a unique identifier, if it gets passed to the application: it can potentially be manipulated by the user. ObjectIDs appear to be generated sequentially, so if you fail to implement the necessary authorization mechanisms, malicious user could simply increment the value he has, to access resources he should not have access to.

我想补充一点,使用自动生成的 BSON ObjectID 作为唯一标识符并不总是一个好主意,如果它被传递给应用程序:它可能会被用户操纵。ObjectIDs 似乎是按顺序生成的,所以如果你没有实现必要的授权机制,恶意用户可以简单地增加他拥有的值,访问他不应该访问的资源。

Therefore using UUID type identifiers will provide a layer of security-through-obscurity. Of course, Authorization (is this user allowed to access requested resource) is a must, but you should be aware of the aforementioned ObjectID feature.

因此,使用 UUID 类型标识符将提供一层安全性。当然,授权(该用户是否允许访问请求的资源)是必须的,但您应该了解上述 ObjectID 功能。

To get the best of both worlds, generate UUID which matches your ObjectID length (12 or 24 characters) and use it to create your own _id of ObjectID type.

为了两全其美,请生成与您的 ObjectID 长度(12 或 24 个字符)相匹配的 UUID,并使用它来创建您自己的 ObjectID 类型的 _id。