简体   繁体   English

如何在 Firestore 中递归搜索结果?

[英]How do I recursively search for results in Firestore?

I'm new to Node and Firebase.我是 Node 和 Firebase 的新手。

I'm currently working on a crafting calculator for a game and have the game items stored in Firebase.我目前正在为游戏制作一个制作计算器,并将游戏项目存储在 Firebase 中。 Some items are composite items, for example:有些项目是复合项目,例如:

1 Lumber Plank = 5 Logs

Based on such requirements, I've structured all the items as a single collection titled as items in Firebase.基于这样的要求,我将所有项目组织成一个单一的集合,在 Firebase 中命名为items

Log would be persisted as:日志将被持久化为:

{
  "type": "basic",
  "name": "log"
}

While lumber plank would be:虽然木板是:

{
  "type": "composite",
  "name": "lumber plank",
  "materials": ["log"],
  "material_values": [5]
}

With such a structure, I'm trying to construct a crafting tree by recursively searching through the database.有了这样的结构,我试图通过递归搜索数据库来构建一个制作树。 A final structure would look as such:最终的结构如下所示:

{
    "name": "board",
    "count": 1,
    "materials": [
        {
            "name": "lumber plank",
            "count": 1,
            "materials": [
                {
                    "name": "log",
                    "count": 5,
                    "materials": null
                }
            ]
        }
    ]
}

I'm having trouble with understanding the callbacks while debugging and this piece of code currently returns undefined followed by log (I'm assuming this comes from the console.log within the search function).我在调试时无法理解回调,这段代码当前返回undefined后跟log (我假设这来自search功能中的console.log )。

async function search(item, result, count) {
    let calcItem = {
        name: item,
        count: count
    };

    db.collection("items")
        .doc(item)
        .get()
        .then(doc => {
            const data = doc.data();
            if (data.type === basic) {
                calcItem.materials = null;
                result.push(calcItem);
                return result;
            } else {
                let materials = data.materials;
                let materialsCount = data.material_values;
                calcItem.materials = [];
                for (let i = 0; i < materials.length; i++) {
                    console.log(materials[i]);
                    search(materials[i], calcItem.materials, materialsCount[i]);
                }
            }
        });
}

let item = "lumber plank";

search(item, [], 1).then(result => console.log(result));

Would appreciate any pointers/tips here.将不胜感激这里的任何指示/提示。 Thanks谢谢


Following feedback from Doug,根据道格的反馈,

I've kinda refactored my code based on your comments and I'm seeing some progress.我已经根据您的评论重构了我的代码,并且我看到了一些进展。

function recursiveSearch(item, count, result) {
    let calcItem = {
        name: item,
        count: count
    };

    dbSearch(item).then(function (doc) {
        const data = doc.data();
        console.log(data);

        if (data.type === basic) {
            calcItem.materials = null;
            result.push(calcItem);
            return result;
        } else {
            let materials = data.materials;
            let materialsCount = data.material_values;
            calcItem.materials = [];
            for (let i = 0; i < materials.length; i++) {
                recursiveSearch(materials[i], materialsCount[i], calcItem.materials);
            }
        }
    });
}

function dbSearch(item) {
    return Promise.resolve(db.collection("items")
        .doc(item)
        .get()
        .then());
}

Log now outputs the search correctly.日志现在可以正确输出搜索。

{
  material_values: [ 5 ],
  materials: [ 'log' ],
  name: 'lumber plank',
  type: 'composite'
}
{
  name: 'log',
  type: 'basic'
}

However, if I understand it correctly, if I were to add in this line it's still going to return undefined, am I right?但是,如果我理解正确,如果我在这一行中添加它仍然会返回 undefined,对吗?

console.log(recursiveSearch("lumber plank", 1, [])

If so, how do I actually log out the entire item structure whilst completing all the recursive searches?如果是这样,我如何在完成所有递归搜索的同时实际注销整个项目结构?

Sorry if the question sounds kinda dumb.对不起,如果这个问题听起来有点愚蠢。 I primarily come from a Java background and dealing with promises/async/await is entirely new to me我主要来自 Java 背景,处理 promises/async/await 对我来说是全新的

You're not dealing with promises correctly.你没有正确处理承诺。 search doesn't actually return a "real" promise, but the caller is expecting it to do so. search实际上并没有返回一个“真实”的承诺,但调用者期望它这样做。 Since it's async , but doesn't return a value directly, it's actually returning is a promise that always resolves to undefined .由于它是async ,但不直接返回值,它实际上返回的是一个始终解析为undefined的承诺。 It's also apparently intended to be a recursive function, which is making it harder to understand (did you mean to return the promise from the inner call to search ?).它显然也打算成为一个递归函数,这使它更难理解(您的意思是从对search的内部调用返回承诺吗?)。

Minimally, you should start by making search return the promise chain that it establishes:至少,您应该首先让搜索返回它建立的承诺链:

return db.collection("item")...get().then()

This will let you receive the value returned by the then callback.这将让您接收then回调返回的值。

I'll also point out that you're started to use async/await syntax, but never committed to using await to make this code more easy to read, which is a bit confusing.我还要指出您已经开始使用 async/await 语法,但从未承诺使用await使这段代码更易于阅读,这有点令人困惑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM