MongoDB查询异常:无法按用户输入筛选关联用户详情
实现关联用户的姓名/邮箱筛选功能
需求
登录用户输入姓名或邮箱后,获取匹配的关联用户详情。
当前问题
目前可获取登录用户的所有关联用户,但无法根据用户输入的内容进行筛选查询。
客户端API调用代码
const handleSearch = async () => { if (!search) { toast({ title: 'Please enter name or email', status: 'error', duration: 5000, isClosable: true, position: 'top', }); return; } try { setloading(true); const config = { headers: { Authorization: `Bearer ${user.token}` }, }; console.log(typeof search); const { data } = await axios.get(`/api/chat?search=${search}`, config); console.log(data); setsearchResults(data); setloading(false); } catch (error) { toast({ title: 'Error occurred', description: 'Failed to load the search results', status: 'error', duration: 5000, isClosable: true, position: 'top', }); setloading(false); } };
后端API处理代码
const fetchChats = expressAsyncHandler(async (req, res) => { console.log('inside fetch chats'); console.log(typeof req.query.search); const keyword = req.query.search ? { $or: [ { name: { $regex: req.query.search, $options: 'i' } }, { email: { $regex: req.query.search, $options: 'i' } }, ], } : {}; console.log('keyword : ', { ...keyword }); try { const currentUserChats = await Chat.find({ users: req.user._id, // ...keyword, }); console.log(currentUserChats, "current user's chats"); const participantIds = currentUserChats.reduce((ids, chat) => { chat.users.forEach((userId) => { if ( userId.toString() !== req.user._id.toString() && !ids.includes(userId.toString()) ) { ids.push(userId.toString()); } }); return ids; }, []); console.log(participantIds, 'retrieved ids'); const users = await User.find({ _id: { $in: participantIds } }).select( '-password' ); res.status(200).send(users); } catch (error) { res.status(400); throw new Error(error.message); } });
补充信息
- API调用正常,
typeof req.query.search为string; - 注释掉
...keyword时,可正常获取无筛选的关联用户; - 需要实现按用户输入的姓名或邮箱筛选关联用户的功能。
解决方案
问题核心在于:针对User集合的筛选条件keyword被错误加到了Chat集合的查询中,而Chat集合并没有name或email字段,导致筛选失效。
正确逻辑是先获取当前用户的所有关联参与者ID,再在查询User集合时同时应用参与者范围和搜索筛选条件。修改后的后端代码如下:
const fetchChats = expressAsyncHandler(async (req, res) => { console.log('inside fetch chats'); console.log(typeof req.query.search); // 获取当前用户所有聊天关联的参与者ID const currentUserChats = await Chat.find({ users: req.user._id }); const participantIds = currentUserChats.reduce((ids, chat) => { chat.users.forEach((userId) => { if ( userId.toString() !== req.user._id.toString() && !ids.includes(userId.toString()) ) { ids.push(userId.toString()); } }); return ids; }, []); console.log(participantIds, 'retrieved ids'); // 构建用户查询条件:限定参与者范围 + 姓名/邮箱匹配(如果有搜索词) const userQuery = { _id: { $in: participantIds } }; if (req.query.search) { userQuery.$or = [ { name: { $regex: req.query.search, $options: 'i' } }, { email: { $regex: req.query.search, $options: 'i' } } ]; } try { const users = await User.find(userQuery).select('-password'); res.status(200).send(users); } catch (error) { res.status(400); throw new Error(error.message); } });
说明
- 先查询当前用户的所有聊天记录,提取出所有关联的参与者ID,确保筛选范围仅限定在这些用户中;
- 将姓名/邮箱的模糊匹配条件添加到
User集合的查询中,而非Chat集合; - 最终返回的是当前用户有聊天关联,且姓名/邮箱匹配搜索词的用户列表。
内容的提问来源于stack exchange,提问作者the3rdeye
相关产品推荐
相关产品推荐

