![](/img/trans.png)
[英]How To Query Firestore to get Document by String Field (Search Engine Friendly Slug)
[英]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.