使用 MongoDB C# 驱动程序连接两个集合的查询中的 NOT IN 过滤器
NOT IN filter in a query with a join of two collections using MongDB C# driver
我有两个可以用这些 classes(简化版)建模的集合:
public class Profile
{
[BsonId]
[BsonRepresentation(BsonType.String)]
public Guid? Id { get; set; }
public string Name { get; set; }
[BsonRepresentation(BsonType.String)]
public Guid UserId { get; set; }
}
public class User
{
[BsonId]
[BsonRepresentation(BsonType.String)]
public Guid? Id { get; set; }
public string UserName { get; set; }
public bool IsConfirmed { get; set; }
}
我需要一个查询来获取所有 User
的 IsConfirmed
标志等于 true 的 UserProfiles
,然后我需要过滤掉 ID 包含在 a 中的那些排除的 ID 列表:
IList<Guid> profileIdsToExclude
这是我到目前为止构建的查询:
var professionalProfilesQuery =
(from profileCollection in _mongoContext.Database.GetCollection<Profile>("profiles").AsQueryable()
join userCollection in _mongoContext.Database.GetCollection<User>("users").AsQueryable()
on profileCollection.UserId equals userCollection.Id.Value
into users
orderby profileCollection.Name
select new ProfessionalProfile
{
Id = profileCollection.Id,
Name = profileCollection.Name,
UserId = profileCollection.UserId,
IsConfirmed = users.First().IsConfirmed,
})
.Where(p => p.IsConfirmed && !profileIdsToExclude.Contains(p.Id.Value));
其中ProfessionalProfile
是一个class到return的查询结果:
public class ProfessionalProfile
{
public Guid? Id { get; set; }
public string Name { get; set; }
public Guid UserId { get; set; }
public bool IsConfirmed { get; set; }
}
我得到了 UserProfiles,只有 IsConfirmed
等于 true 的。但是那些 ID 在被排除的 ID 列表中的那些不会被过滤掉,而是被查询return编辑。
知道我想做的事情是否可行以及如何实现吗?
提前致谢。
你这里的问题是由于类型混淆引起的。
驱动程序创建的查询在末尾包含一个 $match
阶段,看起来有点像这样:
{
$match: {
IsConfirmed: true,
Id: {
$nin: [ BinData(3, "DBA38D51FC28094BA2D6439E95643A49") ]
}
}
}
所以它实际上是在尝试排除具有特定 Guid 值的字段的结果。但是,您正在为您的 Guid 存储字符串,因此过滤器不会排除任何内容。为了解决这个问题,您可以这样做:
改变
.Where(p => p.IsConfirmed && !profileIdsToExclude.Contains(p.Id.Value));
进入
.Where(p => p.IsConfirmed && !profileIdsToExclude.Contains(p.Id));
和
IList<Guid> profileIdsToExclude
进入
IList<Guid?> profileIdsToExclude
我有两个可以用这些 classes(简化版)建模的集合:
public class Profile
{
[BsonId]
[BsonRepresentation(BsonType.String)]
public Guid? Id { get; set; }
public string Name { get; set; }
[BsonRepresentation(BsonType.String)]
public Guid UserId { get; set; }
}
public class User
{
[BsonId]
[BsonRepresentation(BsonType.String)]
public Guid? Id { get; set; }
public string UserName { get; set; }
public bool IsConfirmed { get; set; }
}
我需要一个查询来获取所有 User
的 IsConfirmed
标志等于 true 的 UserProfiles
,然后我需要过滤掉 ID 包含在 a 中的那些排除的 ID 列表:
IList<Guid> profileIdsToExclude
这是我到目前为止构建的查询:
var professionalProfilesQuery =
(from profileCollection in _mongoContext.Database.GetCollection<Profile>("profiles").AsQueryable()
join userCollection in _mongoContext.Database.GetCollection<User>("users").AsQueryable()
on profileCollection.UserId equals userCollection.Id.Value
into users
orderby profileCollection.Name
select new ProfessionalProfile
{
Id = profileCollection.Id,
Name = profileCollection.Name,
UserId = profileCollection.UserId,
IsConfirmed = users.First().IsConfirmed,
})
.Where(p => p.IsConfirmed && !profileIdsToExclude.Contains(p.Id.Value));
其中ProfessionalProfile
是一个class到return的查询结果:
public class ProfessionalProfile
{
public Guid? Id { get; set; }
public string Name { get; set; }
public Guid UserId { get; set; }
public bool IsConfirmed { get; set; }
}
我得到了 UserProfiles,只有 IsConfirmed
等于 true 的。但是那些 ID 在被排除的 ID 列表中的那些不会被过滤掉,而是被查询return编辑。
知道我想做的事情是否可行以及如何实现吗?
提前致谢。
你这里的问题是由于类型混淆引起的。
驱动程序创建的查询在末尾包含一个 $match
阶段,看起来有点像这样:
{
$match: {
IsConfirmed: true,
Id: {
$nin: [ BinData(3, "DBA38D51FC28094BA2D6439E95643A49") ]
}
}
}
所以它实际上是在尝试排除具有特定 Guid 值的字段的结果。但是,您正在为您的 Guid 存储字符串,因此过滤器不会排除任何内容。为了解决这个问题,您可以这样做:
改变
.Where(p => p.IsConfirmed && !profileIdsToExclude.Contains(p.Id.Value));
进入
.Where(p => p.IsConfirmed && !profileIdsToExclude.Contains(p.Id));
和
IList<Guid> profileIdsToExclude
进入
IList<Guid?> profileIdsToExclude