Discord.js结合MongoDB查询匹配question字段多结果实现问题
MongoDB查询匹配问题解决方案
原嵌套数组结构(questionAdd为数组)的修复方案
你之前的代码返回全部内容的原因是:$elemMatch 在查询条件里的作用是筛选符合条件的文档,不会过滤返回的questionAdd数组内容,所以只要文档里有一个匹配的问答项,就会返回整个文档的全部内容。
如果要只返回匹配的数组项,需要在投影参数里也加上$elemMatch过滤,修改后的代码如下:
var test2 = "What fast food chain has the most locations globally?"; await Data.findOne( // 查询条件:筛选包含匹配问答项的文档 { questionAdd: { $elemMatch: { question: {$regex: test2, $options: 'i'} } } }, // 投影:只返回匹配的questionAdd数组项,其他字段按需保留 { _id: 0, questionAdd: { $elemMatch: { question: {$regex: test2, $options: 'i'} } } }, (err, data)=>{ if(data){ var getData = JSON.stringify(data); // 替换toString为JSON序列化更清晰 console.log(getData); } } )
如果需要返回同一个文档里所有匹配的数组项,把投影里的$elemMatch换成$filter聚合操作符即可。
调整后扁平化结构的说明与修复
这个结构每个文档对应一条问答,可以正常返回多个匹配结果,你的原有代码存在3个可优化问题:
- 空结果判断错误:
Data.find没有匹配结果时返回的是空数组[],空数组的布尔值为true,所以!data永远不会触发,要改成data.length === 0判断 - 存在
await和回调函数混用的问题,统一用async/await写法逻辑更清晰 - 正则可以加上
i选项实现不区分大小写匹配,省去提前转小写的冗余操作
修改后的参考代码:
let messageArgs1 = args.join(' '); let outString = messageArgs1.replace(/[`~!@#$%^&()_|+\-=?;'",.<>\{\}\[\]\\\/]/gi, ''); let messageArgs = outString.trim(); if(messageArgs === "") return message.channel.send("Please type your question!"); try { const data = await Data.find( { question: { $regex: messageArgs, $options: 'i' } }, { question: 1, answer: 1, _id: 0 } ).limit(9); if(data.length === 0) { console.log('无匹配结果'); return message.channel.send(`Nope!`); } // 这里处理匹配结果,data就是包含最多9条匹配问答的数组 } catch (err) { console.error('查询错误:', err); }
内容的提问来源于stack exchange,提问作者Và Thi Thi
相关产品推荐
相关产品推荐

