简体   繁体   English

Mongo C# 驱动如何嵌套ElemMatch

[英]Mongo C# Driver how to do nested ElemMatch

If I have following architecture - how do I find zoos with noisy animals?如果我有以下架构 - 我如何找到有嘈杂动物的动物园? Example Data Model示例数据 Model

public class Zoo
{
    public List<Cage> Cages { get; set; }
}

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


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

public class Feline : Animal
{
    public int MeowsCount { get; set; }
}

public class Canine: Animal
{
    public int BarksCount { get; set; }
}

For now I do extract whole db and find necessary with LINQ现在我确实提取了整个数据库并发现有必要使用 LINQ

public IEnumerable<Zoo> FindNoisyZoos(int soundsCount)
{
    var allZoos = await zooCollection.Find(_ => true).ToListAsync();

    List<Zoo> noisyZoos = allZoos.Where(z => 
        z.Cages.Any(c => 
            c.Animals.Where(a => ((Feline)a).MeowsCount == soundsCount || ((Canine)a).BarksCount == soundsCount))))
        .ToList();

    return noisyZoos;
}

And thats terribly inefficient.那是非常低效的。 I would like being able to do nested ElemMatch, but I can't wrap my head around how ElemMatch works.我希望能够进行嵌套的 ElemMatch,但我无法理解 ElemMatch 的工作原理。 I expect it to be something like this:我希望它是这样的:

public IEnumerable<Zoo> FindNoisyZoos(int soundsCount)
{
    var noisyFelineFilter = new FilterDefinitionBuilder<Animal>().And(new FilterDefinitionBuilder<Animal>().OfType<Feline>(), new FilterDefinitionBuilder<Animal>().Eq(a => ((Feline)a).MeowsCount == soundsCount));
    var noisyCanineFilter = new FilterDefinitionBuilder<Animal>().And(new FilterDefinitionBuilder<Animal>().OfType<Canine>(), new FilterDefinitionBuilder<Animal>().Eq(a => ((Canine)a).BarksCount == soundsCount));

    var noisyAnimalFilter = new FilterDefinitionBuilder<Animal>().Or(noisyFelineFilter, noisyCanineFilter);
        

    // smth like this: new FilterDefinitionBuilder<Zoo>().ElemMatch(z => z.Cages.ElemMatch(c => c.Animals.ElemMatch(noisyAnimalFilter)));
    var noisyFilter;
    
    var zoos = await zooCollection.Find(noisyFilter).ToListAsync();

    return zoos;
}

MongoDB .NET driver can process some LINQ queries server-side. MongoDB .NET 驱动程序可以在服务器端处理一些 LINQ 查询。 It translates them under the hood into MongoDB native ones.它在引擎盖下将它们翻译成 MongoDB 原生的。 Did you try something like zooCollection.AsQueriable().Where(z => z...).ToList() .您是否尝试过类似zooCollection.AsQueriable().Where(z => z...).ToList()类的方法。 .ToList() comes last and sends data to the client. .ToList()在最后并向客户端发送数据。 If this works, the filtering will be performed server-side, if it doesn't the driver will tell you directly that it is not supported.如果可行,过滤将在服务器端执行,如果不行,驱动程序将直接告诉您它不受支持。

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

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