Mongoose无法展示私有消息问题求助(MEAN栈开发)
私有消息展示异常问题排查与修复
我刚接触Mongoose与Node.js,在MEAN栈开发环境中遇到私有消息展示异常:消息的发送者、接收者及内容已正常存入数据库,但查看两个用户的对话时,该对话会错误显示在所有用户的消息标签页中。
相关代码
消息Schema定义
var messageSchema = new mongoose.Schema({ id: { type: Number, }, senderId: { type: Number }, senderUsername: { type: String }, recipientId: { type: Number }, recipientUsername: { type: String }, content: { type: String, required:true }, dateRead: { type: Date }, messageSent: { type: Date }, senderDeleted: { type: Boolean }, recipientDeleted: { type: Boolean } }, { collection: 'messages', timestamps: true }, ); module.exports = mongoose.model('Messages', messageSchema)
用户路由(获取消息线程)
//Get Message Of User usersRoute.route("/messages/thread/:username/:senderUsername").get((req, res) => { Messages.find(({ data: { "$in" : [req.params.senderUsername,req.params.username]} }, (error, data) => { if (error) { console.log(error) throw error; } res.json(data); })) })
消息服务层
getMessageThread(username: string,sender:string) { return this.http.get<Message[]>(`${AUTH_API}messages/thread/${username}/${sender}`); }
Angular组件逻辑(member-messages.ts)
import { Component, OnInit, Input } from '@angular/core'; import { NgForm } from '@angular/forms'; import { Message } from 'src/app/models/message'; import { User } from 'src/app/models/user'; import { AccountService } from 'src/app/services/account.service'; import { MessageService } from 'src/app/services/message.service'; import { Observable, take } from 'rxjs' import { ActivatedRoute } from '@angular/router'; import { MembersService } from 'src/app/services/members.service'; @Component({ selector: 'app-member-messages', templateUrl: './member-messages.component.html', styleUrls: ['./member-messages.component.css'] }) export class MemberMessagesComponent implements OnInit { @Input() username: string; @Input() messages: Message[]; user: User; member: any; currentUser$: Observable<User | null>; messageContent: string; constructor( private messageService: MessageService, private accountService: AccountService, private route: ActivatedRoute, private memberService: MembersService ) { this.accountService.currentUser$.pipe(take(1)).subscribe(x => { this.currentUser$ = this.accountService.currentUser$; this.user = x as User; }); } ngOnInit() { const username = this.route.snapshot.paramMap.get('username') as string; this.memberService.getMember(username).subscribe(member => { this.member = member; }); } sendMessage(form: NgForm) { this.messageService.sendMessage(this.username, this.messageContent, this.user) .subscribe((message) => { this.messages.push(message as Message); form.reset(); }) } }
Angular模板(member-messages.html)
<div class="card"> <div class="card-body"> <ng-container *ngIf="messages && messages.length; else noMessages"> <ul class="chat"> <li *ngFor="let message of messages.slice().reverse()"> <span class="chat-img float-right"> <img class="rounded-circle" *ngIf="message.senderUsername && member.username == message.recipientUsername" src="{{user.profile_img || './assets/user.jpg'}}"> <span *ngIf="message.senderUsername && member.username == message.recipientUsername" style="color:red"> {{message.senderUsername}}</span> <img class="rounded-circle" *ngIf="message.recipientUsername && member.username != message.recipientUsername " src="{{member.profile_img || './assets/user.jpg'}}"><span *ngIf="message.recipientUsername && member.username != message.recipientUsername" style="color:green"> {{member.username}}</span> </span> <div class="chat-body" > <p >{{message.content}}</p> </div> </li> </ul> </ng-container> <ng-template #noMessages>No messages Yet... say hi bu using the message box bellow</ng-template> </div> <div class="card-footer"> <form #messageForm="ngForm" (ngSubmit)="sendMessage(messageForm)" autocomplete="off"> <div class="input-group"> <input name="messageContent" required [(ngModel)]="messageContent" type="text" class="form-control input-sm" placeholder="Send a private message"> <div class="input-group-append"> <button [disabled]="!messageForm.valid" class="btn btn-primary" style="border-radius:0px 5px 5px 0px"type="submit"> Send </button> </div> </div> </form> </div> </div>
问题根源与修复
问题所在
路由中的查询逻辑完全错误:
- 使用了Schema中不存在的
data字段进行$in匹配,导致查询条件无效,返回了所有消息文档; - 未正确筛选出仅属于当前两个用户之间的对话,即消息的发送者和接收者必须是这两个用户的组合。
修复后的路由代码
//Get Message Of User usersRoute.route("/messages/thread/:username/:senderUsername").get((req, res) => { const { username, senderUsername } = req.params; // 筛选条件:仅保留两个用户之间的双向消息 Messages.find({ $or: [ { senderUsername: senderUsername, recipientUsername: username }, { senderUsername: username, recipientUsername: senderUsername } ] }, (error, data) => { if (error) { console.log(error); return res.status(500).json({ error: error.message }); } res.json(data); }); });
额外优化建议
- 数据库查询添加排序,按消息发送时间正序排列,避免前端手动反转数组:
Messages.find({ ... }).sort({ messageSent: 1 }).exec((error, data) => { ... })
- 前端模板中移除
slice().reverse(),直接使用排序后的数组; - 错误处理优化:不要直接
throw error,而是返回标准HTTP错误响应给前端,便于前端捕获处理。
内容的提问来源于stack exchange,提问作者BeatrixKiddo
相关产品推荐
相关产品推荐

