MongoDB 使用 Linq 加入
MongoDB join using Linq
CommentCollection
{
"_id":"5b63f0f23846b70011330889",
"CommentType":"task",
"EntityReferenceId":"6082ef25-6f9a-4874-a832-f72e0f693409",
"CommentLink":null,
"EntityName":"task2",
"participants":[
ObjectId("52ffc4a5d85242602e000000"),
ObjectId("52ffc4a5d85242602e000001")
],
"Threads":[
{
"_id":"69bcef71-3695-4340-bdec-4a6e4c58c490",
"CommentType":"task",
"UserId":ObjectId("52ffc4a5d85242602e000000"),
"CommentByUserType":"Admin",
"EntityReferenceId":"6082ef25-6f9a-4874-a832-f72e0f693409",
"Content":"fdffd",
"ProjectName":null,
"PostedDate":"2018-08-03T13:03:05.939Z",
"Active":true,
"Attachment":[
]
}
另一个合集是
userCollection
{
"Id":ObjectId("52ffc4a5d85242602e000000"),
"Name":"Pms Admin",
"Email":"pms@xtrastaff.com",
"Type":"Admin",
"UserId":"6082ef25-6f9a-4874-a832-f72e0f693409",
"UserImage":"6082ef25-6f9a-4874-a832-f72e0f693409"
}
在 CommentCollection 中有一个 "participants" 数组,用于存储用户的 ID(来自用户集合)。
我的要求是加入这两个集合,以便在我的 asp.net 核心项目 (Linq) 中获取用户详细信息。参与者包含 ID 列表
在 Mongo shell 中,您将使用 $lookup which can be used on arrays like in this 示例,您的查询可能如下所示:
db.Comment.aggregate([
{
$lookup: {
from: "user",
localField: "participants",
foreignField: "Id",
as: "participants"
}
}
])
它只是用第二个集合中的对象数组替换参与者:
{
"_id" : "5b63f0f23846b70011330889",
"CommentType" : "task",
"EntityReferenceId" : "6082ef25-6f9a-4874-a832-f72e0f693409",
"CommentLink" : null,
"EntityName" : "task2",
"participants" : [
{
"_id" : ObjectId("5b6e875b9d52833fbe9879c2"),
"Id" : ObjectId("52ffc4a5d85242602e000000"),
"Name" : "Pms Admin",
"Email" : "pms@xtrastaff.com",
"Type" : "Admin",
"UserId" : "6082ef25-6f9a-4874-a832-f72e0f693409",
"UserImage" : "6082ef25-6f9a-4874-a832-f72e0f693409"
}
],
"Threads" : //...
}
在 C# 中,您可以使用 Lookup
语法来表示。第一个选项允许您获得 BsonDocument
类型的列表,它只是跳过类型检查:
var collection = db.GetCollection<Comment>("Comment");
List<BsonDocument> result = collection.Aggregate()
.Lookup("user", "participants", "Id", "participants")
.ToList();
您不能在此处使用常规 LINQ join
的原因是您实际上是在用标量值比较数组(这应该在连接的 equals
部分中)。但是,如果您需要强类型结果而不是 BsonDocuments
,您可以使用不同版本的 Lookup
方法,该方法接受类型和表达式而不是字符串。所以你需要另一个 class 来获得 $lookup
结果,这可以使用继承来解决:
public class Comment
{
public string _id { get; set; }
public string CommentType { get; set; }
public string EntityReferenceId { get; set; }
public string CommentLink { get; set; }
public string EntityName { get; set; }
public ObjectId[] participants { get; set; }
public Thread[] Threads { get; set; }
}
public class CommentWithUsers : Comment
{
public User[] Users { get; set; }
}
然后可以得到CommentWithUser
的列表:
var comments = mydb.GetCollection<Comment>("Comment");
var users = mydb.GetCollection<User>("user");
List<CommentWithUser> result = comments.Aggregate()
.Lookup<Comment, User, CommentWithUsers>(
users,
x => x.participants,
x => x.Id,
x => x.Users).ToList();
CommentCollection
{
"_id":"5b63f0f23846b70011330889",
"CommentType":"task",
"EntityReferenceId":"6082ef25-6f9a-4874-a832-f72e0f693409",
"CommentLink":null,
"EntityName":"task2",
"participants":[
ObjectId("52ffc4a5d85242602e000000"),
ObjectId("52ffc4a5d85242602e000001")
],
"Threads":[
{
"_id":"69bcef71-3695-4340-bdec-4a6e4c58c490",
"CommentType":"task",
"UserId":ObjectId("52ffc4a5d85242602e000000"),
"CommentByUserType":"Admin",
"EntityReferenceId":"6082ef25-6f9a-4874-a832-f72e0f693409",
"Content":"fdffd",
"ProjectName":null,
"PostedDate":"2018-08-03T13:03:05.939Z",
"Active":true,
"Attachment":[
]
}
另一个合集是
userCollection
{
"Id":ObjectId("52ffc4a5d85242602e000000"),
"Name":"Pms Admin",
"Email":"pms@xtrastaff.com",
"Type":"Admin",
"UserId":"6082ef25-6f9a-4874-a832-f72e0f693409",
"UserImage":"6082ef25-6f9a-4874-a832-f72e0f693409"
}
在 CommentCollection 中有一个 "participants" 数组,用于存储用户的 ID(来自用户集合)。
我的要求是加入这两个集合,以便在我的 asp.net 核心项目 (Linq) 中获取用户详细信息。参与者包含 ID 列表
在 Mongo shell 中,您将使用 $lookup which can be used on arrays like in this 示例,您的查询可能如下所示:
db.Comment.aggregate([
{
$lookup: {
from: "user",
localField: "participants",
foreignField: "Id",
as: "participants"
}
}
])
它只是用第二个集合中的对象数组替换参与者:
{
"_id" : "5b63f0f23846b70011330889",
"CommentType" : "task",
"EntityReferenceId" : "6082ef25-6f9a-4874-a832-f72e0f693409",
"CommentLink" : null,
"EntityName" : "task2",
"participants" : [
{
"_id" : ObjectId("5b6e875b9d52833fbe9879c2"),
"Id" : ObjectId("52ffc4a5d85242602e000000"),
"Name" : "Pms Admin",
"Email" : "pms@xtrastaff.com",
"Type" : "Admin",
"UserId" : "6082ef25-6f9a-4874-a832-f72e0f693409",
"UserImage" : "6082ef25-6f9a-4874-a832-f72e0f693409"
}
],
"Threads" : //...
}
在 C# 中,您可以使用 Lookup
语法来表示。第一个选项允许您获得 BsonDocument
类型的列表,它只是跳过类型检查:
var collection = db.GetCollection<Comment>("Comment");
List<BsonDocument> result = collection.Aggregate()
.Lookup("user", "participants", "Id", "participants")
.ToList();
您不能在此处使用常规 LINQ join
的原因是您实际上是在用标量值比较数组(这应该在连接的 equals
部分中)。但是,如果您需要强类型结果而不是 BsonDocuments
,您可以使用不同版本的 Lookup
方法,该方法接受类型和表达式而不是字符串。所以你需要另一个 class 来获得 $lookup
结果,这可以使用继承来解决:
public class Comment
{
public string _id { get; set; }
public string CommentType { get; set; }
public string EntityReferenceId { get; set; }
public string CommentLink { get; set; }
public string EntityName { get; set; }
public ObjectId[] participants { get; set; }
public Thread[] Threads { get; set; }
}
public class CommentWithUsers : Comment
{
public User[] Users { get; set; }
}
然后可以得到CommentWithUser
的列表:
var comments = mydb.GetCollection<Comment>("Comment");
var users = mydb.GetCollection<User>("user");
List<CommentWithUser> result = comments.Aggregate()
.Lookup<Comment, User, CommentWithUsers>(
users,
x => x.participants,
x => x.Id,
x => x.Users).ToList();