【问题标题】:Is there a way to batch read firebase documents有没有办法批量读取firebase文档
【发布时间】:2020-04-21 16:26:57
【问题描述】:

我正在使用 Flutter 和 Firebase 作为我的后端来制作一个移动应用程序。

我有一个存储用户信息的用户文档集合。其中一个字段是一个引用数组(另一个集合中的引用文档),我想在批处理之类的操作中使用它,然后允许读取所有文档。

我知道批处理只允许写入数据库,我的第二个选项是事务,它需要在读取后写入,我试图避免。

有没有一种方法可以在一个操作中读取多个文档而无需使用 Transaction?

【问题讨论】:

  • 你的最后一句话我不清楚。请编辑问题以解释您要通过通常对事务执行的批处理来完成什么。如果您提供文档内容的具体示例,将会很有帮助。
  • 对不起,我的校对应该做得更好
  • 您可以使用 IN 查询一次性按 ID 加载多达 10 个文档。见stackoverflow.com/questions/46721517/…。如果您需要超过 10 个文档,则必须执行多个查询,因此您不妨单独加载它们。
  • 感谢您的回答,该链接也很有帮助。

标签: arrays firebase flutter google-cloud-firestore


【解决方案1】:

Firestore 不提供正式的批量读取 API。正如弗兰克在他的评论中提到的,有一种方法可以使用IN 来使用它们的 ID 从单个集合中获取多个文档。但是,所有文档必须在同一个集合中,并且每个查询不能超过 10 个文档。您最好只为每个文档单独获取(),因为IN 查询有限制,并且不能保证执行速度比个人获得的速度快。这两种解决方案都不能保证是“一致的”,因此在任何给定的时间点,获取的任何一个文档都可能比其他文档“更新鲜”。

【讨论】:

  • 感谢道格的回答,虽然我试图从不同的集合中获取多个文档,所以 IN 不一定能解决我的问题。您的回答有助于我了解 Firebase 的功能和限制。
  • @doug-stevenson“并且每个查询不能超过 10 个文档”,文档只提到“使用 IN 运算符在同一字段上组合最多 10 个相等 (==) 子句“据我了解,限制是您可以在一个字段上查询多达 10 个相等子句并返回尽可能多的文档。不只是 10 个文件,我错了吗?
  • @Yahine 是的,但在这种情况下,他正在对 id 属性执行 IN 查询。所以这里也是一样的。
  • 如果您按字段排序并且对要返回的文档数量有限制,则使用 IN 比使用串行获取有好处。使用 IN 查询,这些可能都来自单个字段值,因为它可能有更多文档并且它填充了“限制”,而通过并发获取时,您必须将限制应用于每个获取(导致到总读取数的 10 倍),然后在最后进行排序,然后根据需要截断。
【解决方案2】:

Firestore 有一个 REST API,允许您使用可能是您需要的文档路径执行批量 GET。

https://firebase.google.com/docs/firestore/reference/rest/v1beta1/projects.databases.documents/batchGet

【讨论】:

    【解决方案3】:

    如果您知道需要获取的文档 ID 和文档的集合路径,您始终可以使用在 firebase Admin SDK 中公开的 getAll() 方法(至少对于 Node.js 环境)。

    然后,例如,您可以编写一个HTTPS Callable Function 来接受绝对文档路径列表并使用getAll() 方法对它们执行“批量获取”操作。

    例如

    // Import firebase functionality
    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    
    // Configure firebase app
    admin.initializeApp(functions.config().firebase);
    
    // HTTPS callable function
    exports.getDocs = functions.https.onCall((data, context) => {
    
        const docPathList = data.list; // e.g. ["users/Jkd94kdmdks", "users/8nkdjsld", etc...]
        const firestore = admin.firestore();
    
        var docList = [];
    
        for (var i = 0; i <= docPathList.length - 1; i++) {
    
            const docPath = docPathList[i];
            const doc = firestore.doc(docPath);
            docList.push(doc);
        }
    
        // Get all
        return firestore.getAll(...docList)
            .then(results => {
                return { data : results.map(doc => doc.data()) };
            })
            .catch(err => {
                return { error : err };
            })
    });
    

    不确定您可以使用 getAll() 获取的文档数量的限制(如果有)是多少,但我知道我的应用程序能够使用此方法每次调用成功获取至少 50 个文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      • 1970-01-01
      • 2021-09-15
      相关资源
      最近更新 更多