简体   繁体   English

如何在文档中查询 Firestore 搜索名称?

[英]How to query a firestore search for a name within a document?

What i have set up for my firestore database is one collection called 'funkoPops'.我为我的 firestore 数据库设置的是一个名为“funkoPops”的集合。 That has documents that are genres of funkoPops, with an array of funkoData that holds all pops for that genre.其中包含 funkoPops 类型的文档,以及包含该类型所有流行音乐的 funkoData 数组。 it looks like this below它看起来像下面这样


I should also note, that the collection funkoPops has hundreds of documents of 'genres' which is basically the funko pop series with the sub collections of funkoData that I web scraped and now need to be able to search through the array field of 'funkoData' to match the name field with the given search parameter.我还应该注意,funkoPops 集合有数百个“流派”文档,这基本上是 funko pop 系列,我 web 抓取了 funkoData 的子 collections,现在需要能够搜索“funkoData”的数组字段将名称字段与给定的搜索参数匹配。

collection: funkoPops => document: 2014 Funko Pop Marvel Thor Series => fields: funkoData: [ 
{
  image: "string to hold image",
  name: "Loki - with helmet",
  number: "36"
},
{
  image: "string to hold image",
  name: "Black and White Loki with Helmet - hot topic exsclusive",
  number: "36"
},
{
etc...
}

So how could i run a query in firestore to be able to search in collection('funkoPops'), search through the document fields for name.那么我如何在 firestore 中运行查询以便能够在集合中搜索('funkoPops'),在文档字段中搜索名称。

I have the ability to search for genres like so, which gives the genre back and the document with the array of data below:我有能力像这样搜索流派,这会返回流派和带有以下数据数组的文档:

const getFunkoPopGenre = async (req, res, next) => {
  try {
    console.log(req.params);
    const genre = req.params.genre;
    const funkoPop = await firestore.collection("funkoPops").doc(genre);
    const data = await funkoPop.get();
    if (!data.exists) {
      res.status(404).send("No Funko Pop found with that search parameter");
    } else {
      res.send(data.data());
    }
  } catch (error) {
    res.status(400).send(error.message);
  }
};

what i am trying to use to search by the field name is below and returns an empty obj:我试图用来按字段名称搜索的内容如下并返回一个空 obj:

const getFunkoPopName = async (req, res, next) => {
  try {
    const name = req.params.name;
    console.log({ name });
    const funkoPop = await firestore
      .collection("funkoPops")
      .whereEqualTo("genre", name);
    const data = await funkoPop.get();
    console.log(data);
    res.send(data.data());
  } catch (error) {
    res.status(400).send(error);
  }
};

Any help would be great, thanks!任何帮助都会很棒,谢谢!

So the way i went about answering this as it seems from top comment and researching a little more on firebase, you do you have to match a full string to search using firebase queries.所以我回答这个问题的方式似乎来自顶级评论,并在 firebase 上进行了更多研究,你是否必须匹配一个完整的字符串才能使用 firebase 查询进行搜索。 Instead, I query all docs in the collection, add that to an array and then forEach() each funkoData.相反,我查询集合中的所有文档,将其添加到数组中,然后 forEach() 每个 funkoData。 From there i then create a matchArray and go forEach() thru the new funkoData array i got from the first query.然后我从那里创建一个 matchArray 和 go forEach() 通过我从第一个查询中获得的新 funkoData 数组。 Then inside that forEach() I have a new variable in matches which is filter of the array of data, to match up the data field name with.inlcudes(search param) and then push all the matches into the matchArr and res.send(matchArr).然后在那个 forEach() 里面我有一个新的变量,它是数据数组的过滤器,将数据字段名称与.inlcudes(search param) 匹配,然后将所有匹配项推送到 matchArr 和 res.send(匹配Arr)。 Works for partial of the string as well as.includes() matches full and substring.适用于部分字符串以及 .includes() 匹配完整和 substring。 Not sure if that is the best and most efficient way but I am able to query thru over probably 20k data in 1-2 seconds and find all the matches.不确定这是否是最好和最有效的方法,但我能够在 1-2 秒内查询大约 20k 数据并找到所有匹配项。 Code looks like this代码看起来像这样

try {
    const query = req.params.name.trim().toLowerCase();
    console.log({ query });
    const funkoPops = await firestore.collection("test");
    const data = await funkoPops.get();
    const funkoArray = [];
    if (data.empty) {
      res.status(404).send("No Funko Pop records found");
    } else {
      data.forEach((doc) => {
        const funkoObj = new FunkoPop(doc.data().genre, doc.data().funkoData);
        funkoArray.push(funkoObj);
      });
      const matchArr = [];
      funkoArray.forEach((funko) => {
        const genre = funko.genre;
        const funkoData = funko.funkoData;
        const matches = funkoData.filter((data) =>
          data.name.toLowerCase().includes(query)
        );
        if (Object.keys(matches).length > 0) {
          matchArr.push({
            matches,
            genre,
          });
        }
      });
      if (matchArr.length === 0) {
        res.status(404).send(`No Funko Pops found for search: ${query}`);
      } else {
        res.send(matchArr);
      }
    }
  } catch (error) {
    res.status(400).send(error.message);
  }

with a little bit of tweaking, i am able to search for any field in my database and match it with full string and substring as well.稍作调整,我就可以在我的数据库中搜索任何字段,并将其与完整字符串和 substring 匹配。

update更新

ended up just combining genre, name, and number searches into one function so that whenver someone searches, the query param is used for all 3 searches at once and will give back data on all 3 searches as an object so that we can do whatever we like in front end:最终只是将类型、名称和数字搜索组合到一个 function 中,这样当有人搜索时,查询参数将同时用于所有 3 个搜索,并将所有 3 个搜索的数据作为 object 返回,这样我们就可以做任何我们想做的事情就像在前端:

const getFunkoPopQuery = async (req, res) => {
  try {
    console.log(req.params);
    const query = req.params.query.trim().toLowerCase();
    const funkoPops = await firestore.collection("test");
    const data = await funkoPops.get();
    const funkoArr = [];
    if (data.empty) {
      res.status(404).send("No Funko Pop records exsist");
    } else {
      data.forEach((doc) => {
        const funkoObj = new FunkoPop(doc.data().genre, doc.data().funkoData);
        funkoArr.push(funkoObj);
      });

      // genre matching if query is not a number
      let genreMatches = [];
      if (isNaN(query)) {
        genreMatches = funkoArr.filter((funko) =>
          funko.genre.toLowerCase().includes(query)
        );
      }
      if (genreMatches.length === 0) {
        genreMatches = `No funko pop genres with search: ${query}`;
      }

      // name & number matching
      const objToSearch = {
        notNullNameArr: [],
        notNullNumbArr: [],
        nameMatches: [],
        numbMatches: [],
      };

      funkoArr.forEach((funko) => {
        const genre = funko.genre;
        if (funko.funkoData) {
          const funkoDataArr = funko.funkoData;
          funkoDataArr.forEach((data) => {
            if (data.name) {
              objToSearch.notNullNameArr.push({
                funkoData: [data],
                genre: genre,
              });
            }
            if (data.number) {
              objToSearch.notNullNumbArr.push({
                funkoData: [data],
                genre: genre,
              });
            }
          });
        }
      });
      // find name that includes query
      objToSearch.notNullNameArr.forEach((funko) => {
        const genre = funko.genre;
        const name = funko.funkoData.filter((data) =>
          data.name.toLowerCase().includes(query)
        );
        if (Object.keys(name).length > 0) {
          objToSearch.nameMatches.push({
            genre,
            name,
          });
        }
      });
      // find number that matches query
      objToSearch.notNullNumbArr.forEach((funko) => {
        const genre = funko.genre;
        const number = funko.funkoData.filter((data) => data.number === query);
        if (Object.keys(number).length > 0) {
          objToSearch.numbMatches.push({
            genre,
            number,
          });
        }
      });

      if (objToSearch.nameMatches.length === 0) {
        objToSearch.nameMatches = `No funko pops found with search name: ${query}`;
      }
      if (objToSearch.numbMatches.length === 0) {
        objToSearch.numbMatches = `No funko pop numbers found with search: ${query}`;
      }

      const searchFinds = {
        genre: genreMatches,
        name: objToSearch.nameMatches,
        number: objToSearch.numbMatches,
      };

      res.send(searchFinds);
    }
  } catch (error) {
    res.status(400).send(error.message);
  }
};

If anyone is well suited in backend and knows more about firestore querying, please let me know!如果有人非常适合后端并了解有关 Firestore 查询的更多信息,请告诉我!

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

相关问题 如何查询Firestore以按字符串字段获取文档(搜索引擎友好的子弹) - How To Query Firestore to get Document by String Field (Search Engine Friendly Slug) 如何根据查询更新 Firestore 上的文档 - How to update a document on Firestore based on query 如何获取firestore collectionGroup查询的父文档? - How to get parent document of firestore collectionGroup query? 如何在 Firestore 查询中获取第二个 10 文档? - How to get the second 10 document in a Firestore Query? firestore firebase 问题:如何在不指定文档名称的情况下更新文档 - firestore firebase problem: how to update the document without specifying the name of the document 如何在忽略 html 标签的 html 文档中突出显示文本查询的搜索结果? - How to highlight the search-result of a text-query within an html document ignoring the html tags? 如何在 Firestore 云 function 中创建带有子集合的文档? - How to create a document with a subcollection within Firestore cloud function? 如何在事务中创建新的 Firestore 文档 - How do you create a new Firestore document within a transaction 如何删除 Firestore 子集合中的文档 - How to delete a document within sub-collection in Firestore 按名称从 firestore 获取文档 - Get a document from firestore by name
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM