首页 文章

MongoDb c#driver按字段值查找数组中的项目

提问于
浏览
21

我发现检查的方法是在简单数组中包含的值:

var filter = Builders<Post>.Filter.AnyEq(x => x.Tags, "mongodb");

但是如何通过具体领域找到包含许多字段的复杂项目?我找到了通过点符号方法用 BsonDocument 构建器编写它的方法,但是如何使用类型化的lambda符号呢?

upd

我觉得它有点像

builderInst.AnyIn(p => p.ComplexCollection.Select(ml => ml.Id), mlIds)

但现在无法检查,有人可以帮忙吗?

4 回答

  • 1

    ElemMatch

    var filter = Builders<Post>.Filter.ElemMatch(x => x.Tags, x => x.Name == "test");
    var res = await collection.Find(filter).ToListAsync()
    
  • 4

    你需要 $elemMatch 运算符 . 您可以使用 Builders<T>.Filter.ElemMatchAny 表达式:

    Find(x => x.Tags.Any(t => t.Name == "test")).ToListAsync()
    

    http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/expressions/#elemmatch

  • 1

    从2.4.2版本的C#驱动程序开始,IFindFluent接口可用于查询数组元素 . ElemMatch不能直接在字符串数组上使用,而find接口可以处理简单或复杂类型(例如“Tags.Name”)并且是强类型的 .

    FilterDefinitionBuilder<Post> tcBuilder = Builders<Post>.Filter;
                FilterDefinition<Post> tcFilter = tcBuilder.Eq("Tags","mongodb") & tcBuilder.Eq("Tags","asp.net");
                   ...
                await myCollection.FindAsync(tcFilter);
    

    Linq驱动程序使用聚合框架,但对于没有聚合运算符的查询,查找更快 .

    请注意,在以前版本的驱动程序中已经破坏了这一点,因此在原始发布时无法获得答案 .

  • 22

    这是一个从数组中返回单个复杂项的示例(使用MongoDB.Driver v2.5.0):

    Simple Data Model

    public class Zoo
    {
        public List<Animal> Animals { get; set; }
    }
    
    public class Animal
    {
        public string Name { get; set; }
    }
    

    Option 1 (Aggregation)

    public Animal FindAnimalInZoo(string animalName)
    {
        var zooWithAnimalFilter = Builders<Zoo>.Filter
            .ElemMatch(z => z.Animals, a => a.Name == animalName);
    
        return _db.GetCollection<Zoo>("zoos").Aggregate()
            .Match(zooWithAnimalFilter)
            .Project<Animal>(
                Builders<Zoo>.Projection.Expression<Animal>(z => 
                    z.Animals.FirstOrDefault(a => a.Name == animalName)))
            .FirstOrDefault(); // or .ToList() to return multiple
    }
    

    Option 2 (Filter & Linq) 这对我来说慢了大约5倍

    public Animal FindAnimalInZoo(string animalName)
    {
        // Same as above
        var zooWithAnimalFilter = Builders<Zoo>.Filter
            .ElemMatch(z => z.Animals, a => a.Name == animalName);
    
        var zooWithAnimal = _db.GetCollection<Zoo>("zoos")
            .Find(zooWithAnimalFilter)
            .FirstOrDefault();
    
        return zooWithAnimal.Animals.FirstOrDefault(a => a.Name == animalName);
    }
    

相关问题