Firestore比较两个集合文档的速度非常慢。

3

我目前正在将手机用户的联系人上传到Firestore数据库中,这些内容与IT技术有关。

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

我的结构如下:

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

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

我的收集中大约有50,000个电话号码,每个都作为一个文档。这将在之后大大增加,可能会增加到1百万。

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

我正在尝试检查一个特定已知uid和db_contacts集合中的公共号码。已知uid在db_contacts集合中存在多少个号码。
我的云功能将如下所示:
  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秒,必须更快。如何加速?

1个回答

5

当您查找常见文档时,会依次获取一个文档并等待其返回,然后再获取下一个文档并等待...我之前没有使用过async/await,但我会尝试以下方法:

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);
            }
        });
    });
});

我无法感谢你的足够!我已经为此苦苦挣扎了一段时间,而你刚刚解决了它!非常感谢! - Lambasoft
嘿,巴托洛缪,有没有可能只返回5个共同的数字?在Promise.all中获取到5个结果后,我能否停止其中的Promise呢? - Lambasoft
不用谢!我添加了一段代码片段来帮助你。你能编辑一下你的问题,这样其他人也可以看到我的回答吗? - Bartholomew Furrow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接