Node.js 通过 MongoDB 数据库表达不区分大小写的搜索(过滤器)
Node.js Express case-insensitive search (filter) through MongoDB database
我想进行不区分大小写的搜索 API(我正在使用 Express、Mongoose 和 Angular)。我的 Angular 应用程序和输入字段中有数据 table。所以我的 API 应该 return 我的数据(onChange)。我有两个集合(容器和容器类型)。
我希望它的工作方式与此示例完全相同:https://www.w3schools.com/jquery/jquery_filters.asp?fbclid=IwAR3klbA6BJQ_a3wTRf8legaucd4S_2Ns6j8QGQjElgVCrEbde6HT3DSZz38
这次搜索 API return 给我正确的数据字段(所有者、标识号和制造商,它们在单独的集合中,但我从其他集合中成功获取了)。但是这个 API 当我写 FULL STRING 时我列出的 return 是我的数据,它不能通过写字母来工作。
router.get("/search", async (req, res) => {
try {
const { searchString } = req.body;
const containers = await Container.aggregate([
{
$lookup: {
from: "containerstypes",
localField: "containerTypeID",
foreignField: "_id",
as: "containerTypes",
},
},
{ $unwind: "$containerTypes" },
{
$match: {
$or: [
{ owner: searchString },
{ IdentificationNo: searchString },
{ "containerTypes.manufacturer": searchString },
],
},
},
]);
res.status(200).json(containers);
} catch (err) {
res.status(404).json({ success: false, msg: "Container not found" });
}
});
感谢大家的帮助。我在这里使用聚合,但如果可能的话,我可以不用聚合框架。为了仅在我的 table 中列出数据,我使用了查找和填充函数。
最好在您要搜索的字段上创建文本索引。
在你的模型文件中你可以这样创建索引,
schema.index({owner: 'text', IdentificationNo: 'text'});
schema.index({'containerTypes.manufacturer': 'text'});
搜索使用 $text
和 $search
运算符,
await Container.find({$text: {$search: searchString }});
这里的问题是您不能在聚合函数中使用 $text,它只能作为管道中的第一阶段使用,这对您的情况没有用。
如果可能,我建议将 containersType 集合嵌入到容器集合中
我找到了解决办法。我只是在每个 SearchString 之前包含了 $regex。现在它可以工作,但是 我会很感激,因为我没有太多现实世界的经验,如果有人能告诉我,这是不是好的解决方案。
router.get("/search", async (req, res) => {
try {
const { searchString } = req.body;
const containers = await Container.aggregate([
{
$lookup: {
from: "containerstypes",
localField: "containerTypeID",
foreignField: "_id",
as: "containerTypes",
},
},
{ $unwind: "$containerTypes" },
{
$match: {
$or: [
{ owner: { $regex: searchString, $options: "i" } },
{ IdentificationNo: { $regex: searchString, $options: "i" } },
{
"containerTypes.manufacturer": {
$regex: searchString,
$options: "i",
},
},
],
},
},
]);
res.status(200).json(containers);
} catch (err) {
res.status(404).json({ success: false, msg: "Container not found" });
}
});
我想进行不区分大小写的搜索 API(我正在使用 Express、Mongoose 和 Angular)。我的 Angular 应用程序和输入字段中有数据 table。所以我的 API 应该 return 我的数据(onChange)。我有两个集合(容器和容器类型)。 我希望它的工作方式与此示例完全相同:https://www.w3schools.com/jquery/jquery_filters.asp?fbclid=IwAR3klbA6BJQ_a3wTRf8legaucd4S_2Ns6j8QGQjElgVCrEbde6HT3DSZz38
这次搜索 API return 给我正确的数据字段(所有者、标识号和制造商,它们在单独的集合中,但我从其他集合中成功获取了)。但是这个 API 当我写 FULL STRING 时我列出的 return 是我的数据,它不能通过写字母来工作。
router.get("/search", async (req, res) => {
try {
const { searchString } = req.body;
const containers = await Container.aggregate([
{
$lookup: {
from: "containerstypes",
localField: "containerTypeID",
foreignField: "_id",
as: "containerTypes",
},
},
{ $unwind: "$containerTypes" },
{
$match: {
$or: [
{ owner: searchString },
{ IdentificationNo: searchString },
{ "containerTypes.manufacturer": searchString },
],
},
},
]);
res.status(200).json(containers);
} catch (err) {
res.status(404).json({ success: false, msg: "Container not found" });
}
});
感谢大家的帮助。我在这里使用聚合,但如果可能的话,我可以不用聚合框架。为了仅在我的 table 中列出数据,我使用了查找和填充函数。
最好在您要搜索的字段上创建文本索引。 在你的模型文件中你可以这样创建索引,
schema.index({owner: 'text', IdentificationNo: 'text'});
schema.index({'containerTypes.manufacturer': 'text'});
搜索使用 $text
和 $search
运算符,
await Container.find({$text: {$search: searchString }});
这里的问题是您不能在聚合函数中使用 $text,它只能作为管道中的第一阶段使用,这对您的情况没有用。
如果可能,我建议将 containersType 集合嵌入到容器集合中
我找到了解决办法。我只是在每个 SearchString 之前包含了 $regex。现在它可以工作,但是 我会很感激,因为我没有太多现实世界的经验,如果有人能告诉我,这是不是好的解决方案。
router.get("/search", async (req, res) => {
try {
const { searchString } = req.body;
const containers = await Container.aggregate([
{
$lookup: {
from: "containerstypes",
localField: "containerTypeID",
foreignField: "_id",
as: "containerTypes",
},
},
{ $unwind: "$containerTypes" },
{
$match: {
$or: [
{ owner: { $regex: searchString, $options: "i" } },
{ IdentificationNo: { $regex: searchString, $options: "i" } },
{
"containerTypes.manufacturer": {
$regex: searchString,
$options: "i",
},
},
],
},
},
]);
res.status(200).json(containers);
} catch (err) {
res.status(404).json({ success: false, msg: "Container not found" });
}
});