我有以下结构,我希望聚集在一组电影中,以获取所有演员及其形象。
{
"_id" : 1,
"Title" : "Pirates of the Caribbean: The Curse of the Black Pearl",
"Actors" : [
{
"Name" : "Johnny Depp",
"NameInMovie" : "Captain Jack Sparrow",
"ImageUrl" : "Johnny-Depp.png"
},
{
"Name" : "Geoffrey Rush",
"NameInMovie" : "Captain Hector Barbossa",
"ImageUrl" : "Geoffrey-Rush.png"
},
{
"Name" : "Orlando Bloom",
"NameInMovie" : "Will Turner",
"ImageUrl" : "Orlando-Bloom.png"
}
]
},
{
"_id" : 2,
"Title" : "Pirates of the Caribbean: At World's End",
"Actors" : [
{
"Name" : "Johnny Depp",
"NameInMovie" : "Captain Jack Sparrow",
"ImageUrl" : "Johnny-Depp.png"
},
{
"Name" : "Geoffrey Rush",
"NameInMovie" : "Captain Hector Barbossa",
"ImageUrl" : "Geoffrey-Rush.png"
},
{
"Name" : "Orlando Bloom",
"NameInMovie" : "Will Turner",
"ImageUrl" : "Orlando-Bloom.png"
}
]
}
尝试使用Linq AsQueryable函数获取结果,但不支持:
var actors = Movies
.AsQueryable()
.SelectMany(x => x.Actors)
.GroupBy(x => x.Name)
.Select(a => a.First())
.ToList();
如何使用MongoDB driver2
结果应该像
{"Name" : "Johnny Depp",
"ImageUrl" : "Johnny-Depp.png" },
{"Name" : "Geoffrey Rush",
"ImageUrl" : "Geoffrey-Rush.png" },
{"Name" : "Orlando Bloom",
"ImageUrl" : "Orlando-Bloom.png" }
解决
var actors = Movies.AsQueryable()
.SelectMany(x => x.Actors)
.GroupBy(x => new Actor { Name = x.Name, ImageUrl = x.ImageUrl })
.Select(x => x.Key)
.ToList();
这提供了以下查询
[{
"$unwind": "$Actors"
},
{
"$project": {
"Actors": "$Actors",
"_id": 0
}
},
{
"$group": {
"_id": {
"ImageUrl": "$Actors.ImageUrl",
"Name": "$Actors.Name"
}
}
},
{
"$project": {
"_id": "$_id"
}
}]
答案 0 :(得分:1)
你很接近,但在$group
:
var results = Movies.AsQueryable()
.SelectMany( x => x.Actors )
.GroupBy( x => x.Name )
.Select( x => new { Name = x.Key, ImgUrl = x.First().ImageUrl })
.ToArray();
所以.Select()
实际上需要与您使用的语法不同的语法。这为您提供了一个序列化的管道:
[
{
"$unwind" : "$Actors"
},
{
"$project" : {
"Actors" : "$Actors",
"_id" : 0
}
},
{
"$group" : {
"_id" : "$Actors.Name",
"__agg0" : {
"$first" : "$Actors.ImageUrl"
}
}
},
{
"$project" : {
"Name" : "$_id",
"ImgUrl" : "$__agg0",
"_id" : 0
}
}
],
哪个恕我直言并非完全“最佳”,但这就是你使用LINQ界面所获得的。
交替出现:
var results = Movies.AsQueryable()
.SelectMany( x => x.Actors )
.GroupBy( x => new { Name = x.Name, ImgUrl = x.ImageUrl })
.ToArray();
出现如下:
[
{
"$unwind" : "$Actors"
},
{
"$project" : {
"Actors" : "$Actors",
"_id" : 0
}
},
{
"$group" : {
"_id" : {
"Name" : "$Actors.Name",
"ImgUrl" : "$Actors.ImageUrl"
}
}
}
],
哪个不使用$first
,因此不是“完全”相同的东西,但它确实在您的情况下得出相同的结果,因为ImgUrl
始终是每个{的相同值Name
上的{1}}。