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

Go操作MongoDB:如何在$or查询中实现特定匹配场景的条数限制

Go操作MongoDB实现单对端ID最多返回5条记录的方案

该逻辑可直接在MongoDB侧通过聚合管道实现,无需拉取全量数据到应用层过滤,性能可控。

实现思路

整体通过聚合管道分阶段处理数据:

  • 第一阶段先复用原有过滤规则,提前筛出符合基础条件的记录,缩小后续计算范围
  • 第二阶段为每条命中记录计算对应的对端参与方ID:如果当前传入ID匹配partnerA,对端就是partnerB.id;如果匹配partnerB,对端就是partnerA.id
  • 第三阶段通过窗口函数按对端ID分区,按业务指定的排序规则(如创建时间倒序、记录ID倒序)为每个分区内的记录生成顺序编号
  • 第四阶段过滤掉分区内编号大于5的记录,实现单个对端最多返回5条的限制
  • 第五阶段清理计算过程中生成的临时字段,返回和普通查询结构一致的原始文档

代码实现(基于官方mongo-go-driver)

// currentID 为接口传入的待匹配参与方ID
currentID := "your_input_id"
pipeline := mongo.Pipeline{
	// 阶段1:基础条件匹配,完全复用原有过滤逻辑
	{{"$match", bson.D{
		{"unlocked", false},
		{"deletedAt", nil},
		{"$or", bson.A{
			bson.D{
				{"partnerA.id", currentID},
				{"partnerA.looksInteresting", false},
			},
			bson.D{
				{"partnerB.id", currentID},
				{"partnerB.looksInteresting", false},
			},
		}},
	}}},
	// 阶段2:计算每条记录对应的对端ID
	{{"$addFields", bson.D{
		{"counterpartyId", bson.D{
			{"$cond", bson.D{
				{"if", bson.D{{"$eq", bson.A{"$partnerA.id", currentID}}}},
				{"then", "$partnerB.id"},
				{"else", "$partnerA.id"},
			}},
		}},
	}}},
	// 阶段3:按对端ID分区,生成组内序号,排序规则可根据业务调整,示例用_id倒序
	{{"$setWindowFields", bson.D{
		{"partitionBy", "$counterpartyId"},
		{"sortBy", bson.D{{"_id", -1}}},
		{"output", bson.D{
			{"recordRank", bson.D{
				{"$documentNumber", bson.D{}},
			}},
		}},
	}}},
	// 阶段4:每个对端ID仅保留前5条记录
	{{"$match", bson.D{
		{"recordRank", bson.D{{"$lte", 5}}},
	}}},
	// 阶段5:移除临时字段,返回原始文档结构
	{{"$unset", bson.A{"counterpartyId", "recordRank"}}},
}

// 执行聚合查询
cursor, err := yourCollection.Aggregate(ctx, pipeline)
if err != nil {
	// 自行处理错误
}
// 后续解析cursor的逻辑和普通find查询一致

版本兼容提示:上述用到的$setWindowFields窗口函数要求MongoDB版本 >= 5.0。如果使用的是更早的版本,可以替换为$group按对端ID分组+$slice取每组前5条+$unwind还原结构的方案,逻辑等价但性能略低于窗口函数实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:00:53