繁体   English   中英

如何在C#Mongodb强类型驱动程序中基于嵌套数组元素进行过滤

[英]How to filter based on nested array element in C# Mongodb strongly typed driver

我使用官方C#MongoDb强类型驱动程序版本2.7.0-beta001与Windows 10计算机上的MongoDB v 4.0-rc1进行交互。

考虑以下类:

public class Library
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    public DateTime DateAdded { get; set; }

    public DateTime LastModified { get; set; }

    public string Title { get; set; }

    public Author Author { get; set; }

    public bool AllBooks { get; set; }
}

public class Author {
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string BirthDate { get; set; }

    public string ScientificDegree { get; set; }

    public List<Book> Books { get; set; }
}

public class Book
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }

    public string Title { get; set; }

    public int PublishYear { get; set; }

    public string Content { get; set; }

    public bool IsVerified { get; set; }
}

如果所有作者书籍都经过验证,如何更新库文档,这是我的代码:

string libraryId = GetLibraryId();

var repository = _database.GetCollection<Library>("Libraries");

var filter = Builders<Library>.Filter.Where(l => l.Id == libraryId &&
                l.Author.Books.All(b => b.IsVerified == true));

var update = Builders<Library>.Update.Set(l => l.AllBooks, true);

await repository.UpdateOneAsync(filter, update);

最后一行抛出System.ArgumentException:Unsupported filter:All

在您的POCO类中, Books是一个.NET列表,因此您可以(理论上)使用所有扩展方法(如All )。 问题是它不是对象的LINQ,所以这个表达式不在内存中计算。 MongoDB驱动程序正在尝试将其转换为MongoDB查询,因为您可以看到MongoDB查询语言中没有相应的运算符。

你可以做什么 ? 您可以尝试将此过滤器重写为其他内容(保持相同的逻辑含义)。 例如,您可以使用$ elemMatch 您可以构建查询,尝试查找至少有一本等于false的书的文档,然后使用$not来否定该条件,而不是尝试查找IsVerified等于true的所有书籍。 在这种情况下, $elemMatch有用:

$ elemMatch运算符匹配包含数组字段的文档,其中至少有一个元素匹配所有指定的查询条件。

所以不能至少一个表示

然后你的代码看起来像这样:

var col = mydb.GetCollection<Library>("Libraries");
var filter = Builders<Library>.Filter.Not(
    Builders<Library>.Filter.ElemMatch(x => x.Author.Books, b => b.IsVerified == false));

var update = Builders<Library>.Update.Set(l => l.AllBooks, true);

await col.UpdateManyAsync(filter, update);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM