【问题标题】:Firestore Comparing two collection documents is very slowFirestore 比较两个集合文档很慢
【发布时间】:2023-03-31 00:55:01
【问题描述】:

我目前正在将我的移动用户的电话联系人上传到 Firestore 数据库。

平均一个用户有大约 500 个电话号码,而我将有大约 1000 个用户。

我的结构如下:

Firestore-root
    |
    --- users_contacts (collection)
         |
         --- uid (document)
              |
              --- contacts (subcollection)
                   |
                   --- phoneNumberOfContact (document)
                          |
                          --- phoneNumberOfContact: true

我还有另一个集合,其中存储了我想与特定用户的联系人进行比较的一般电话号码。

我那里有大约 50,000 个电话号码,每个都作为文件。这将在以后大大增加,可能达到 100 万。

Firestore-root
    |
    --- db_contacts (collection)
         |
         --- phoneNumber (document)
              |
              --- phoneNumber: true

我正在尝试检查特定已知 uid 和 db_contacts 集合的常用号码。 db_contacts 集合中存在多少个已知 uid。

我的云功能如下:

  1. 获取联系人的所有电话号码
    • 首先我只想获取用户文档的 id,因为 id 是电话号码,希望它能加快处理速度。但它似乎在 Javascript 中是不可能的,因为 snapshotChanges() 不存在。
  2. 遍历获取的联系人并检查联系人是否存在于 db_contacts 中。由于我已经知道检查它是否存在的参考路径,所以这应该很快
  3. 返回所有常用联系人

如果 JavaScript 中有 snapshotChanges() 的替代方法,我的脚本会运行得更快。我的思路对吗?

到目前为止我做了什么:

exports.findCommonNumbers = functions.https.onCall((data, context) => {
    return new Promise((resolve, reject) => {
        fetchCommonNumbers().then((commonNumbers) => {
            console.log(commonNumbers);
            resolve("Done");
        }).catch((err) => {
            console.log(err);
            reject("Error Occured");
        });


    });
});

async function fetchCommonNumbers() {
    var commonNumbers = [];

    let contactsReference = admin.firestore().collection("user_contacts").doc("iNaYVsDCg3PWsDu67h75xZ9v2vh1").collection("contacts");
    const dbContactReference = admin.firestore().collection('db_contacts');

    userContacts = await contactsReference.get();
    userContacts = userContacts.docs;
    for(var i in userContacts){
        var userContact = userContacts[i];
        const DocumentID = userContact.ref.id;
        //Check if Document exist 
        dbContact = await dbContactReference.doc(DocumentID).get();
        if (dbContact.exists) {
            commonNumbers.push(DocumentID);
        }
    }

    return Promise.resolve(commonNumbers);
}

函数 findCommonNumbers 需要 60 秒才能执行。它必须快得多。我怎样才能让它更快?

【问题讨论】:

    标签: javascript node.js firebase google-cloud-firestore


    【解决方案1】:

    当您寻找共同的文档时,您正在获取一个,等待它回来,获取下一个,等待它......我以前没有使用过异步/等待,但我会做类似的事情:

    Promise.All(userContacts.map(userContact => {
        const DocumentID = userContact.ref.id;
        //Check if Document exists
        return dbContactReference.doc(DocumentID).get().then(dbContact => {
            if (dbContact.exists) {
                commonNumbers.push(DocumentID);
            }
        });
    }));
    

    抱歉代码片段和错误;我在手机上。这应该同时请求它们。

    编辑:在所有东西都返回后返回:

    new Promise((resolve, reject) => {
        var returned = 0;
        userContacts.map(userContact => {
            const DocumentID = userContact.ref.id;
            //Check if Document exists
            dbContactReference.doc(DocumentID).get().then(dbContact => {
                if (dbContact.exists) {
                    commonNumbers.push(DocumentID);
                }
                returned++;
                if (returned == userContact.length || commonNumbers.length >= 5) {
                    resolve(commonNumbers);
                }
            });
        });
    });
    

    【讨论】:

    • 感激不尽!我已经为此苦苦挣扎了一段时间,而您刚刚解决了!非常感谢!
    • 嘿 Bartholomew,是否有可能只返回 5 个常用数字?获取 5 个结果后,我可以停止 promise.all 中的承诺吗?
    • 不客气!添加了一个代码 sn-p 来帮助解决这个问题。您能否编辑您的问题,以便其他人可以看到我的回答?
    猜你喜欢
    • 2020-10-29
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多