ReactJS+MongoDB+Node.js环境下搜索副标题无法返回精准匹配结果问题
问题排查
你遇到的问题由两个核心错误导致:
- 前端逻辑错误:你当前在前端基于已有的
props.data筛选副标题ID再传给后端,这一逻辑本身不合理,且未给输入框设置name属性,会导致状态更新异常。 - 后端查询逻辑错误:你直接用
find返回匹配的完整Title文档,没有过滤文档内的副标题子数组,因此会带出同Title下所有的副标题内容。
修复方案
前端修改
- 先给两个输入框补充
name属性,确保状态可以正常更新
<TextField label="Title" name="title" value={this.state.title} onChange={this.handleFilterChange} /> <TextField label="Sub-Title" name="subtitle" value={this.state.subtitle} onChange={this.handleFilterChange} />
- 重写
fetch方法,直接将搜索关键词传给后端,去掉前端筛选副标题ID的冗余逻辑
fetch = () => { const data = { title: this.state.title.trim(), subtitle: this.state.subtitle.trim(), }; this.filteringData(data); };
后端修改
改用MongoDB聚合管道实现,先匹配符合条件的Title文档,再过滤副标题子数组,最后过滤掉无匹配副标题的空文档,修改后的代码如下:
getSequence: async function (req, res) { try { const pipeline = [ { $match: { type: 'Title' } } ]; // 匹配标题关键词 if (req.query.title) { pipeline.push({ $match: { titlename: new RegExp(req.query.title, 'i') } }); } // 过滤匹配的副标题 if (req.query.subtitle) { const subReg = new RegExp(req.query.subtitle, 'i'); pipeline.push( // 筛选子数组中匹配的副标题 { $addFields: { children: { $filter: { input: '$children', as: 'sub', cond: { $regexMatch: { input: '$$sub.name', regex: subReg } } } } } }, // 排除无匹配副标题的文档 { $match: { children: { $ne: [] } } } ); } // 执行聚合查询 const result = await titlesubtitle.aggregate(pipeline); const response = { data: result, totalCount: result.length, dataList : result } return res.send(response); } catch (error){ console.error(error); return res.status(500).send('Error'); } }
修改完成后即可完全符合你的预期需求:
- 搜索副标题apple时,仅返回包含apple的记录,无冗余副标题
- 同时搜索Title为Fruits、副标题为pear时,仅返回1条匹配记录
- 无匹配结果时返回空数组,前端渲染为空表
内容的提问来源于stack exchange,提问作者itiDi
相关产品推荐
相关产品推荐

