You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

问题根源与修复

问题所在

路由中的查询逻辑完全错误:

  1. 使用了Schema中不存在的data字段进行$in匹配,导致查询条件无效,返回了所有消息文档;
  2. 未正确筛选出仅属于当前两个用户之间的对话,即消息的发送者和接收者必须是这两个用户的组合。

修复后的路由代码

//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);
  });
});

额外优化建议

  1. 数据库查询添加排序,按消息发送时间正序排列,避免前端手动反转数组:
Messages.find({ ... }).sort({ messageSent: 1 }).exec((error, data) => { ... })
  1. 前端模板中移除slice().reverse(),直接使用排序后的数组;
  2. 错误处理优化:不要直接throw error,而是返回标准HTTP错误响应给前端,便于前端捕获处理。

内容的提问来源于stack exchange,提问作者BeatrixKiddo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 05:39:24