簡體   English   中英

如何在文檔中查詢 Firestore 搜索名稱?

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

我為我的 firestore 數據庫設置的是一個名為“funkoPops”的集合。 其中包含 funkoPops 類型的文檔,以及包含該類型所有流行音樂的 funkoData 數組。 它看起來像下面這樣


我還應該注意,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...
}

那么我如何在 firestore 中運行查詢以便能夠在集合中搜索('funkoPops'),在文檔字段中搜索名稱。

我有能力像這樣搜索流派,這會返回流派和帶有以下數據數組的文檔:

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

我試圖用來按字段名稱搜索的內容如下並返回一個空 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);
  }
};

任何幫助都會很棒,謝謝!

所以我回答這個問題的方式似乎來自頂級評論,並在 firebase 上進行了更多研究,你是否必須匹配一個完整的字符串才能使用 firebase 查詢進行搜索。 相反,我查詢集合中的所有文檔,將其添加到數組中,然后 forEach() 每個 funkoData。 然后我從那里創建一個 matchArray 和 go forEach() 通過我從第一個查詢中獲得的新 funkoData 數組。 然后在那個 forEach() 里面我有一個新的變量,它是數據數組的過濾器,將數據字段名稱與.inlcudes(search param) 匹配,然后將所有匹配項推送到 matchArr 和 res.send(匹配Arr)。 適用於部分字符串以及 .includes() 匹配完整和 substring。 不確定這是否是最好和最有效的方法,但我能夠在 1-2 秒內查詢大約 20k 數據並找到所有匹配項。 代碼看起來像這樣

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

稍作調整,我就可以在我的數據庫中搜索任何字段,並將其與完整字符串和 substring 匹配。

更新

最終只是將類型、名稱和數字搜索組合到一個 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);
  }
};

如果有人非常適合后端並了解有關 Firestore 查詢的更多信息,請告訴我!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM