Golang mongodb 聚合操作

huangapple go评论69阅读模式
英文:

Golang mongodb aggregation

问题

我有一个用户集合。用户有一个 int64 的 "id",还有 "avatar"、"name" 和其他用户 id 的数组。
我想要实现的是查询单个用户,但是不仅仅获取他的朋友 id 数组,还要获取他的朋友数组,包含他们的姓名和头像。在 golang 中如何实现这个目标?我找到了一些类似我需要的东西 - "lookup" 函数,但是我不知道如何正确使用它。

英文:

I have a collection of users. User have an int64 "id", and lets say "avatar", "name" and an array of other users ids.
What I want to achieve is to query SINGLE user, but instead of getting an array with his friends ids I want to get an array of his friends, containing their names and avatars. How to achieve it in golang? I have found some kind of what I need - "lookup" function, but I cannot understand how to use it right.

答案1

得分: 8

你不能直接将 $lookup 应用于数组,但是你可以先使用 $unwind 对其进行展开。

没有示例文档,下面的代码片段只是一个通用的方法:

pipeline := []bson.M{ 
    bson.M{"$match": bson.M{"_id": userId }},
    bson.M{"$unwind": "$otherUsersIdsArrayName"},
    bson.M{
    	"$lookup": bson.M{ 
    		"from": userCollectionName, 
    		"localField": otherUsersIdsArrayName, 
    		"foreignField": "id", 
    		"as": "friend"
    	}
    },
    bson.M{"$unwind": "$friend"},
	bson.M{
		"$group": bson.M{
    		"_id": "id",
    		"id": bson.M{"$first": "$id"},
    		"name": bson.M{"$first": "$name"},
    		"avatar": bson.M{"$first": "$avatar"},
    		otherUsersIdsArrayName: bson.M{ "$push": "$friend"}
    	}
    }
}
pipe := collection.Pipe(pipeline)
resp := []bson.M{}
err = pipe.All(&resp)

我应该提到,聚合/管道返回的是 bson.M,而不是已填充的用户对象。毕竟,Mongo 不是关系型数据库。

英文:

You cannot apply $lookup to array directly, but you can to $unwind it first.

Without example documents, the code snippet below is rather a general approach:

pipeline := []bson.M{ 
    bson.M{"$match": bson.M{"_id": userId }},
    bson.M{"$unwind": "$otherUsersIdsArrayName"},
    bson.M{
    	"$lookup": bson.M{ 
    		"from": userCollectionName, 
    		"localField": otherUsersIdsArrayName, 
    		"foreignField": "id", 
    		"as": "friend"
    	}
    },
    bson.M{"$unwind": "$friend"},
	bson.M{
		"$group": bson.M{
    		"_id": "id",
    		"id": bson.M{"$first": "$id"},
    		"name": bson.M{"$first": "$name"},
    		"avatar": bson.M{"$first": "$avatar"},
    		otherUsersIdsArrayName: bson.M{ "$push": "$friend"}
    	}
    }
}
pipe := collection.Pipe(pipeline)
resp := []bson.M{}
err = pipe.All(&resp)

I should mention that aggregation/pipe returns bson.M, not hydrated User objects. Mongo is not a relational database after all.

huangapple
  • 本文由 发表于 2017年3月16日 20:11:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/42833731.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定