如何批量写入Firestore中的单个文档,其中包含2个或更多自定义类对象?

huangapple go评论73阅读模式
英文:

How to batch write to Firestore on a single document with 2 or more custom class objects

问题

我有3个类:

K1{int字段A, int字段B}
K2{bool字段A, bool字段B, bool字段C}
K3{String字段A}

我想把它们写入单个Firestore文档中。当我尝试:

K1 k1 = new K1...
K2 k2 = new K2...
K3 k3 = new K3...
WriteBatch writeBatch = db.batch();
writeBatch.set(documentReference, k1, SetOptions.merge());
writeBatch.set(documentReference, k2, SetOptions.merge());
writeBatch.set(documentReference, k3, SetOptions.merge());
writeBatch.commit();

只有其中一个被写入。如果它们是3个不同的documentReference,事情会起作用,但如果是同一个就不行。当然,我可以简单地尝试:

documentReference.set(k1, SetOptions.merge()).addOnSuccessListener(
...
documentReference.set(k2, SetOptions.merge()).addOnSuccessListener(
...
documentReference.set(k3, SetOptions.merge());
)
)

那样会起作用,但它会被视为对数据库的3次写入。

有没有一种方法可以使用多个自定义对象的组合或者HashMap和自定义对象进行批量写入同一个文档?
英文:

I have 3 classes:

K1{int field A, int field B} 
K2{bool fA, bool fB, bool fC} 
K3{String fA}

And I want to write them into a single Document in a Firestore. When I try:

K1 k1 = new K1...
K2 k2 = new K2...
K3 k3 = new K3...
WriteBatch writeBatch = db.batch();
writeBatch.set(documentReference, k1, SetOptions.merge());
writeBatch.set(documentReference, k2, SetOptions.merge());
writeBatch.set(documentReference, k3, SetOptions.merge());
writeBatch.commit();

only 1 of them gets written. If those were 3 different documentReference things would work, but not if it's same one. Of course, I could try simply:

documentReference.set(k1, SetOptions.merge()).addOnSuccesListener(
   ...
   documentReference.set(k2, SetOptions.merge()).addOnSuccesListener(
      ...
      documentReference.set(k3, SetOptions.merge());
   )
)

and that would have worked, but it would count as 3 writes to DB.

Is there a way to do a batch write to the same document with a combination of multiple custom objects, or even a HashMap and a custom object?

答案1

得分: 1

你不能使用批处理来更新具有多个值的单个文档,因为文档将仅包含最近写入的最新数据。

如果您需要一个类似这样的文档:

docId(文档)
 |
 --- k1(对象)
 |   |
 |   --- a: 1
 |   |
 |   --- b: 2
 |
 --- k2(对象)
 |   |
 |   --- b: 3
 |   |
 |   --- c: 4
 |
 --- k3(对象)
     |
     --- d: 5
     |
     --- e: 6

您只需创建另一个类:

class Doc {
    public K1 k1;
    public K2 k2;
    public K3 k3;

    public Doc(K1 k1, K2 k2, K3 k3) {
        this.k1 = k1;
        this.k2 = k2;
        this.k3 = k3;
    }
}

然后像这样创建类的新实例:

Doc doc = new Doc(new K1(1, 2), new K2(3, 4), new K3(5, 6));
documentReference.set(doc);

即使您将三个对象传递给构造函数,您始终只需支付一次写操作。

另一方面,如果您需要更新同一文档中的多个字段,那么您应该将这些值传递给DocumentReference#update()方法,正如官方文档中所解释的那样:

P.S.请记住,批量写入仅在您希望在多个不同位置执行操作时才有用。

英文:

You cannot use a batch to update a single document with multiple values, as the document will only contain only the most recent data that was written.

If you need to have a document that looks like this:

docId (document)
 |
 --- k1 (object)
 |   |
 |   --- a: 1
 |   |
 |   --- b: 2
 |
 --- k2 (object)
 |   |
 |   --- b: 3
 |   |
 |   --- c: 4
 |
 --- k3 (object)
     |
     --- d: 5
     |
     --- e: 6

All you have to do is to create another class:

class Doc {
    public K1 k1;
    public K2 k2;
    public K3 k3;

    public Doc(K1 k1, K2 k2, K3 k3) {
        this.k1 = k1;
        this.k2 = k2;
        this.k3 = k3;
    }
}

And then create a new instance of the class like this:

Doc doc = new Doc(new K1(1, 2), new K2(3, 4), new K3(5, 6));
documentReference.set(doc);

Even if you pass three objects to the constructor, you'll always have to pay a single write operation.

On the other hand, if you need to update multiple fields within the same document, then you should pass those values to the DocumentReference#update() method, as explained in the official documentation:

P.S. Remember that a batch write is useful only when you want to perform operations at multiple different locations.

huangapple
  • 本文由 发表于 2023年2月16日 02:03:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75463790.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定