38

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

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

但是如何通过具体字段找到具有多个字段的复杂项目?我找到了使用 builder 通过点符号方法编写它的方法BsonDocument,但是我如何使用类型化的 lambda 符号来编写它?

更新

我认为这是某种

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

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

4

4 回答 4

51

ElemMatch

var filter = Builders<Post>.Filter.ElemMatch(x => x.Tags, x => x.Name == "test");
var res = await collection.Find(filter).ToListAsync()
于 2015-08-04T02:25:58.357 回答
15

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

简单数据模型

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

public class Animal
{
    public string Name { get; set; }
}

选项 1(聚合)

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
}

选项 2(过滤器和 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);
}
于 2018-03-17T07:39:47.693 回答
8

你需要$elemMatch运营商。你可以使用Builders<T>.Filter.ElemMatchor 一个Any表达式:

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

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

于 2015-12-10T13:14:10.173 回答
4

从 C# 驱动程序的 2.4.2 版本开始,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 驱动程序使用聚合框架,但对于没有聚合运算符的查询,查找速度更快。

请注意,这在以前的驱动程序版本中已被破坏,因此在原始发布时答案不可用。

于 2017-02-06T18:25:46.153 回答