TypeORM中orWhere查询失效求助:如何正确组合多查询条件
问题分析与修正方案
原代码核心问题
你的查询构建逻辑存在两处致命错误,导致仅返回共享笔记:
- 重复调用
where()覆盖条件:TypeORM中where()方法会重置整个WHERE子句,你在第一个条件组后再次调用.where("note.mediaId = :mediaId"),直接丢弃了之前的当前用户笔记查询条件。 - OR条件未正确分组:未将「当前用户笔记」和「共享笔记」两个分支用括号包裹,逻辑链混乱。
修正后的查询函数
public async searchByMediaIdCollaboration({ mediaId, query, channelId, channelUserId, params, }: { mediaId: string; query: SearchDto; channelId: string; channelUserId: string; params: any; }) { const queryBuilder = this.dataSource.createQueryBuilder(NoteEntity, "note"); // 按需关联topics表 if (Object.keys(params).includes("topics")) { queryBuilder.leftJoinAndSelect("note.topics", "topic"); } const searchTerm = `%${query.search.toLocaleLowerCase()}%`; queryBuilder // 公共过滤条件:指定频道、指定媒体ID .where("note.channelId = :channelId AND note.mediaId = :mediaId", { channelId, mediaId }) // 搜索关键词匹配:title或note包含关键词 .andWhere("(LOWER(note.title) LIKE :searchTerm OR LOWER(note.note) LIKE :searchTerm)", { searchTerm }) // 核心OR逻辑:当前用户的笔记 OR 开启共享的笔记 .andWhere("(note.channelUserId = :channelUserId OR note.collaborate = :collaborate)", { channelUserId, collaborate: true }); return await queryBuilder.getMany(); }
逻辑说明
- 公共条件前置:先过滤出指定频道、指定媒体ID下的所有笔记,缩小查询范围。
- 关键词匹配:统一处理大小写,确保搜索结果不区分大小写。
- 分组OR条件:用括号明确包裹两个分支,确保满足「当前用户的笔记」或者「开启共享的笔记」任一条件即可。
备选写法(子查询构建器)
如果需要更复杂的分组逻辑,也可以用子查询构建器实现相同效果:
queryBuilder .where("note.channelId = :channelId AND note.mediaId = :mediaId", { channelId, mediaId }) .andWhere("(LOWER(note.title) LIKE :searchTerm OR LOWER(note.note) LIKE :searchTerm)", { searchTerm }) .andWhere(qb => { return qb.where("note.channelUserId = :channelUserId", { channelUserId }) .orWhere("note.collaborate = :collaborate", { collaborate: true }); });
内容的提问来源于stack exchange,提问作者Aaron Balthaser
相关产品推荐
相关产品推荐

