在数组中聚合 C# groupby
Aggregate C# groupby in array
我有以下结构,我想聚合电影列表以获取所有演员及其图像。
{
"_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"
}
}]
您很接近,但在 $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
}
}
],
恕我直言,这并不完全 "optimal",但这就是您使用 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
因此不是 "exactly" 同一件事,但在你的情况下它确实会产生相同的结果,因为 ImgUrl
总是相同的Actor
.
上每个 Name
的值
我有以下结构,我想聚合电影列表以获取所有演员及其图像。
{
"_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"
}
}]
您很接近,但在 $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
}
}
],
恕我直言,这并不完全 "optimal",但这就是您使用 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
因此不是 "exactly" 同一件事,但在你的情况下它确实会产生相同的结果,因为 ImgUrl
总是相同的Actor
.
Name
的值