Firestore可以使用一个查询更新符合条件的多个文档吗?

Dan*_*scu 13 firebase google-cloud-firestore

换句话说,我正试图弄清楚在SQL中与Firestore等价的是什么:

UPDATE table SET field = 'foo' WHERE <condition>`
Run Code Online (Sandbox Code Playgroud)

是的,我问的是如何一次更新多个文档,但与链接的问题不同,我特意询问如何一次性完成此操作,而无需在内存中读取任何内容,因为没有必要在您想要的任何内容时执行此操作是在匹配条件的所有文档上设置标志.

db.collection('table')
  .where(...condition...)
  .update({
    field: 'foo',
  });
Run Code Online (Sandbox Code Playgroud)

是我期望的工作,CollectionReference没有.update方法.

交易及成批写入文档中提到的交易和批量写入.交易结束是因为"事务包含任意数量的get()操作,后跟任意数量的写入操作" 批处理写入也不是解决方案,因为它们逐个文档地工作.

有了MongoDB,就可以了

db.table.update(
  { /* where clause */ },
  { $set: { field: 'foo' } }
)
Run Code Online (Sandbox Code Playgroud)

那么,Firestore可以用一个查询更新多个文档,SQL数据库或MongoDB的工作方式,即不需要为每个文档往返客户端吗?如果没有,怎么能有效地完成?

小智 19

弗兰克的回答实际上很好,确实解决了这个问题。

但是对于那些赶时间的人来说,这个片段可能会对您有所帮助:

const updateAllFromCollection = async (collectionName) => {
    const firebase = require('firebase-admin')

    const collection = firebase.firestore().collection(collectionName)

    const newDocumentBody = {
        message: 'hello world'
    }

    collection.where('message', '==', 'goodbye world').get().then(response => {
        let batch = firebase.firestore().batch()
        response.docs.forEach((doc) => {
            const docRef = firebase.firestore().collection(collectionName).doc(doc.id)
            batch.update(docRef, newDocumentBody)
        })
        batch.commit().then(() => {
            console.log(`updated all documents inside ${collectionName}`)
        })
    })
}
Run Code Online (Sandbox Code Playgroud)

只需更改where查询数据的函数内部的内容以及newDocumentBody每个文档上正在更改的内容。

另外不要忘记使用集合名称调用函数。

  • `firebase.firestore().collection(collectionName).doc(doc.id)` 应替换为 `doc.ref` (3认同)
  • 您可以在 docRef 的初始化中重用“collection”变量,对吧?`const docRef = collection.doc(doc.id)` (2认同)

Fra*_*len 15

在Cloud Firestore中更新文档需要知道其ID.Cloud Firestore不支持SQL的更新查询.

您将始终分两步执行此操作:

  1. 根据您的条件运行查询以确定文档ID
  2. 使用单个更新或单个批量写入更新文档.

请注意,您只需要步骤1中的文档ID.因此,您可以运行仅返回ID的查询.这在客户端SDK中是不可能的,但可以通过REST API和Admin SDK完成,如下所示:如何获取Firestore中的密钥列表?

  • 今天仍然如此吗?如果是这样,路线图是否包含模拟“UPDATE table SET field = 'foo' WHERE &lt;condition&gt;”的 SQL 功能的功能?该文档暗示它仍然是正确的,但对此并没有明确说明。感谢您的帮助! (2认同)
  • 是的,今天仍然如此。 (2认同)

小智 6

最简单的方法是这个

const ORDER_ITEMS = firebase.firestore().collection('OrderItems')

ORDER_ITEMS.where('order', '==', 2)
  .get()
  .then(snapshots => {
    if (snapshots.size > 0) {
      snapshots.forEach(orderItem => {
        ORDER_ITEMS.doc(orderItem.id).update({ status: 1 })
      })
    }
  })
Run Code Online (Sandbox Code Playgroud)