是的,这可能是部分过滤器表达式不能包含任何“非”过滤器的问题。
对于那些可能对此类索引的 C# 解决方案感兴趣的人,这里有一个示例。
我们有一个“用户”实体,它与“医生”实体具有一对一的“关系”。
此关系由“用户”实体中的非必需、可为空的字段“DoctorId”表示。换句话说,要求给定的“医生”一次只能链接到单个“用户”。
所以我们需要一个唯一的索引,当某些东西试图将 DoctorId 设置为已经为任何其他“用户”实体设置的相同 Guid 时,它可以触发异常。同时,“DoctorId”字段必须允许多个“null”条目,因为许多用户没有附加任何医生。
构建这种索引的解决方案如下:
var uniqueDoctorIdIndexDefinition = new IndexKeysDefinitionBuilder<User>()
.Ascending(o => o.DoctorId);
var existsFilter = Builders<User>.Filter.Exists(o => o.DoctorId);
var notNullFilter = Builders<User>.Filter.Type(o => o.DoctorId, BsonType.String);
var andFilter = Builders<User>.Filter.And(existsFilter, notNullFilter);
var createIndexOptions = new CreateIndexOptions<User>
{
Unique = true,
Name = UniqueDoctorIdIndexName,
PartialFilterExpression = andFilter,
};
var uniqueDoctorIdIndex = new CreateIndexModel<User>(
uniqueDoctorIdIndexDefinition,
createIndexOptions);
users.Indexes.CreateOne(uniqueDoctorIdIndex);
可能在您对“用户”实体的描述中,您必须通过使用属性直接指定“DoctorId”字段的 BsonType,例如在我们的例子中是:
[BsonRepresentation(BsonType.String)]
public Guid? DoctorId { get; set; }
我非常确定对于这个问题有一个更精通和紧凑的解决方案,所以如果有人在这里提出建议,我会很高兴。