简体   繁体   English

Firestore:如何在强制执行唯一字段值的同时插入具有自动 ID 的文档?

[英]Firestore: How to insert a document with automatic id while enforcing unique field value?

In Firestore, I have a collection of fruits containing documents with automatically generated ids, and a name property.在 Firestore 中,我有一组水果,其中包含具有自动生成的 ID 和名称属性的文档。
I want to insert a new fruit document, with an automatically generated id, and only if no other with the same name exists.我想插入一个新的水果文档,它有一个自动生成的 id,并且只有在不存在其他同名的情况下。
Inspired by this answer , I try this:受此答案的启发,我尝试这样做:
Edit: For the record, as detailed in the accepted answer: this code is NOT transactionally safe: it does NOT prevent race conditions which could insert the same fruit name under heavy load编辑:作为记录,如已接受的答案中所述:此代码在事务上不是安全的:它不会阻止可能在重负载下插入相同水果名称的竞争条件

const query = firestore.collection(`/fruits`).where("name", "==", "banana").limit(1);

await firestore.runTransaction(async transaction => {
    const querySnapshot = await transaction.get(query);
    if (querySnapshot.length == 0) {
        const newRef = firestore.collection(`/fruits`).doc();
        await transaction.create(newRef, { name: "banana" });
    }
});

But I wonder: is newRef guaranteed to be un-used?但我想知道:是否保证newRef未被使用?
Otherwise, does the transaction automatically retries (due to the create failing) until success?否则,事务是否会自动重试(由于创建失败)直到成功?
Otherwise, how can I insert my fruit?否则,我怎么能插入我的水果呢?

Note: I use the node.js admin SDK, but I think the problem is the same with the javascript API.注意:我用的是node.js admin SDK,但是我觉得问题和javascript API是一样的。

Edit: here is how I do it finally:编辑:这是我最后的做法:

const hash = computeHash("banana"); // md5 or else
const uniqueRef = firestore.doc(`/fruitsNameUnique/${hash}`);

try {
    await firestore.runTransaction(async transaction => {
        transaction.create(uniqueRef, {}); // will fail if banana already exists
        const newRef = firestore.collection(`/fruits`).doc();
        transaction.create(newRef, { name: "banana" });
    });
} catch (error) {
    console.log("fruit not inserted", error.message);
}

is newRef guaranteed to be un-used? newRef 保证不被使用吗?

It is virtually guaranteed to be unique.它几乎可以保证是独一无二的。 The chances of two randomly generated document IDs is astronomically small.两个随机生成的文档 ID 的可能性很小。

See also:也可以看看:

One thing you should be aware of is that your code is not actually transactionally safe.您应该注意的一件事是您的代码实际上不是事务安全的。 There is nothing stopping two clients from adding a new fruit where name=banana in a race condition between the moment of the query and the moment the transaction actually creates the new document.在查询时刻和事务实际创建新文档时刻之间的竞争条件下,没有什么可以阻止两个客户端添加名称=香蕉的新水果。 Under low traffic situations it's probably OK, but you are taking a chance on that.在低流量的情况下,它可能没问题,但你正在抓住机会。

In fact, Firestore doesn't have a built-in way to ensure uniqueness of a document's field value.事实上,Firestore 没有内置方法来确保文档字段值的唯一性。 It will require a fair amount of extra work to implement that yourself, perhaps by using that field value as the unique key in another collection, and making sure that collection is part of a bigger transaction that deals with the documents in your fruits collection.这将需要大量额外的工作来自己实现,也许通过使用该字段值作为另一个集合中的唯一键,并确保该集合是处理水果集合中文档的更大事务的一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 Go 将文档 ID 作为字段值 Firestore 插入 - How to insert document id as a field value Firestore with Go 如何仅使用他的唯一 ID 更新 Firestore 中的文档? - How to update a document in Firestore just using his unique id? 如何更新 Firestore 文档中特定字段的值? - How to update value of a specific field in Firestore document? 如何在将数据作为实时数据库添加到 Cloud Firestore 之前获取 Cloud Firestore 文档的唯一 ID - How to get cloud firestore document unique Id before adding data to cloud firestore as Realtime database 如何通过文档 ID 从 firestore 网站获取特定字段数据 - How get specific Field data by document id from firestore website 如何使用 Cloud firestore 中的文档 ID 访问文档字段? - How can I acess a document field using document id from cloud firestore? 如何在 Firestore 中更改文档数组字段的某个索引的值? - How to change the value of a certain index of an array field of a document in Firestore? 如何在 firestore 9 中将带有自定义 ID 的文档添加到 firestore - How to add Document with Custom ID to firestore in firestore 9 Flutter Firebase 中如何在文档字段中保存文档id - How to save the document id in document field while creating it in Flutter Firebase 如何删除 Firestore 文档中的字段? - How to delete a field in a Firestore Document?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM