![](/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.