简体   繁体   English

在 firestore 的文档中初始创建 map 结构时出现问题

[英]Problem with the initial creation of a map structure within a document in firestore

I have a small problem with the initial setup of my database.我的数据库初始设置有一个小问题。

My structure is this:我的结构是这样的:

数据库

I have an array of codes and a map that maps each code to an integer which will be updated.我有一个代码数组和一个 map,它将每个代码映射到将被更新的 integer。

Everything works as expected.一切都按预期工作。 I use the following code to achieve this goal.我使用下面的代码来实现这个目标。 But there is exactly one problem: The very first writing to this document when it does not exist will not create a map of code: int but will create a field that has the name "comparisons.12345".但确实存在一个问题:当文档不存在时第一次写入该文档不会创建代码为 map 的 int,但会创建一个名为“comparisons.12345”的字段。 So instead of a map, I end up with loads of individual fields (One for each code)因此,我最终得到的不是 map,而是大量的单独字段(每个代码一个)

My workaround is to create the document manually with the empty map. After that everything works as expected我的解决方法是使用空的 map 手动创建文档。之后一切都按预期工作

Of course, I could check on the frontend site if the document exists and add it if not.当然,如果文档存在,我可以在前端站点上检查,如果不存在,则添加它。 But this is a ONE-TIME operation.但这是一次操作。 I do not want to pay for the overhead of checking the document EVERY TIME.我不想支付每次检查文档的开销。 So is there a way of creating it the correct way or do I have to stick to manual creating (Which is not a problem in production, but very annoying during testing)那么有没有一种方法可以以正确的方式创建它,还是我必须坚持手动创建(这在生产中不是问题,但在测试期间非常烦人)

val data = mutableMapOf(
            "codes" to FieldValue.arrayUnion(comp.getCode()),
            "comparisons." + comp.getCode() to FieldValue.increment(1)
        )

db.collection("codes").document("info").update(data as Map<String, Any>)

Update更新

When using set with merge set to true, the behavior is exactly the same when the document does not yet exist.当使用set和 merge 设置为 true 时,行为与文档尚不存在时完全相同。 Instead of the map I need, I get loads of documents with a "dot" in their name like this:我得到的不是我需要的 map,而是名称中带有“点”的大量文档,如下所示:

意想不到的结果

There are two ways in which you can update a document.您可以通过两种方式更新文档。 The first one is when using DocumentReference#update(Map<String, Object> data) which:第一个是使用DocumentReference#update(Map<String, Object> data)时:

Updates fields in the document referred to by this DocumentReference.更新此 DocumentReference 引用的文档中的字段。 If no document exists yet, the update will fail.如果尚不存在文档,则更新将失败。

And the second one is when using DocumentReference#set(Object data, SetOptions options) which:第二个是使用DocumentReference#set(Object data, SetOptions options)时:

Writes to the document referred to by this DocumentReference.写入此 DocumentReference 引用的文档。 If the document does not yet exist, it will be created.如果文档尚不存在,则会创建它。 If you pass SetOptions, the provided data can be merged into an existing document.如果您传递 SetOptions,则可以将提供的数据合并到现有文档中。

So there is no difference between using the update() and the set() method with the merge true option for documents that already exist.因此,对于已存在的文档,使用带有 merge true 选项的update()set()方法没有区别。 The difference between these two operations comes only for documents that don't exist.这两个操作之间的区别仅适用于不存在的文档。 For instance, set() with the merge true option will create the document if the document does not exist, while when using the update(), the operation will fail.例如,如果文档不存在,带有 merge true 选项的 set() 将创建文档,而当使用 update() 时,操作将失败。

So you should use the second option.所以你应该使用第二个选项。 In this way, you'll don't need to check the documents for existence.这样,您就不需要检查文档是否存在。

Edit:编辑:

You're getting:你得到:

comparisons.12345

Because of the way you're trying to perform the update.由于您尝试执行更新的方式。 To be able to perform an update to an element that exists within an object (map), you have to use another map:为了能够对 object(地图)中存在的元素执行更新,您必须使用另一个 map:

val increment = mutableMapOf(
            comp.getCode() to FieldValue.increment(1)
        )
val data = mutableMapOf(
            "codes" to FieldValue.arrayUnion(comp.getCode()),
            "comparisons" to increment
        )
db.collection("codes").document("info").set(data, SetOptions.merge())

The above code will work only if comp.getCode() returns 12345 .上面的代码只有在comp.getCode()返回12345时才有效。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM