【问题标题】:Batch get DocumentReferences?批量获取 DocumentReferences?
【发布时间】:2018-11-23 05:12:28
【问题描述】:

我正在尝试改进 firestore 获取功能,我有类似的东西:

    return admin.firestore().collection("submissions").get().then(
        async (x) => {
            var toRet: any = [];
            for (var i = 0; i < 10; i++) {
                try {
                    var hasMedia = x.docs[i].data()['mediaRef'];
                    if (hasMedia != null) {
                        var docData = (await x.docs[i].data()) as MediaSubmission;

                        let submission: MediaSubmission = new MediaSubmission();
                        submission.author = x.docs[i].data()['author'];
                        submission.description = x.docs[i].data()['description'];

                        var mediaRef = await admin.firestore().doc(docData.mediaRef).get();
                        submission.media = mediaRef.data() as MediaData;
                        toRet.push(submission);
                    }
                }
                catch (e) {
                    console.log("ERROR GETTIGN MEDIA: " + e);
                }
            }
            return res.status(200).send(toRet);
        });

第一次get很好,但是性能最差就行了:

var mediaRef = await admin.firestore().doc(docData.mediaRef).get();

我认为这是因为调用没有批处理。

是否可以批量获取 mediaRef 数组以提高性能?

基本上我有一个文档集合,这些文档的外部引用由指向单独集合中路径的字符串存储,并且事实证明获取这些引用很慢。

【问题讨论】:

    标签: javascript typescript firebase google-cloud-firestore


    【解决方案1】:

    这个呢?我进行了一些重构以使用更多等待/异步代码,希望我的 cmets 有所帮助。

    主要思想是使用Promise.all并等待所有mediaRefs检索

    async function test(req, res) {
      // get all docs
      const { docs } = await admin
        .firestore()
        .collection('submissions')
        .get();
    
      // get data property only of docs with mediaRef
      const datas = await Promise.all(
        docs.map(doc => doc.data()).filter(data => data.mediaRef),
      );
    
      // get all media in one batch - this is the important change
      const mediaRefs = await Promise.all(
        datas.map(({ mediaRef }) =>
          admin
            .firestore()
            .doc(mediaRef)
            .get(),
        ),
      );
    
      // create return object
      const toRet = datas.map((data: MediaSubmission, i) => {
        const submission = new MediaSubmission();
        submission.author = data.author;
        submission.description = data.description;
    
        submission.media = mediaRefs[i].data() as MediaData;
    
        return submission;
      });
      return res.status(200).send(toRet);
    }
    

    【讨论】:

    • 嘿,这肯定更快,我将其标记为答案。我认为一个小错误是您在创建提交时没有返回它,因此 toRet 变成了一大堆空值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    相关资源
    最近更新 更多