【问题标题】:Query with filter builder on nested array using MongoDB C# driver使用 MongoDB C# 驱动程序在嵌套数组上使用过滤器生成器进行查询
【发布时间】:2015-09-08 06:01:25
【问题描述】:

考虑以下存储为文档的对象结构:

public class Foo
{
    public string Id { get; set; }
    public ICollection<FooBar> Bars { get; set; }

    // ...
}

public class FooBar
{
    public string BarId { get; set; }

    // ...
}

使用带有驱动程序的 LINQ 样式查询,我可以 Find 所有包含 FooFooBar BarId 像这样:

var foos = await m_fooCollection.Find( f => f.Bars.Any( fb => fb.BarId == "123") ).ToListAsync();

如何使用FilterDefinitionBuilder 而不是Find 上的内联LINQ 来实现相同的查询?

【问题讨论】:

  • 它不是 LINQ,只是一个 lambda 表达式。
  • ICollection 上的.AnySystem.Linq 命名空间中Enumerable 类的一部分,对吧?
  • 确实如此,但永远不会调用该方法。驱动程序将表达式转换为 mongo 查询。
  • 好的,有道理。我想我更想表达一个事实,即我使用的是 LINQ 样式语法而不是实际的 LINQ。
  • 是的,这并不重要。只是给未来的谷歌员工的一个说明。

标签: c# mongodb mongodb-query mongodb-.net-driver mongodb-csharp-2.0


【解决方案1】:

您需要执行的查询使用$elemMatch 查询运算符。

所以,这个查询使用了 lambda 表达式

var findFluent = collection.Find(f => f.Bars.Any(fb => fb.BarId == "123"));

相当于这个查询使用FilterDefinitionBuilder:

var findFluent = collection.Find(Builders<Foo>.Filter.ElemMatch(
    foo => foo.Bars, 
    foobar => foobar.BarId == "123"));

【讨论】:

  • 如果我有 BarNumber 属性而不是 BarId 并且有 2 个具有相同值的 BarNumber。我怎样才能同时获得它们?
  • @i3arnon,这将返回与条件匹配的所有 Foo 对象,每个对象都有其所有 FooBar 子对象。如果我也需要过滤这些子对象(使用BarId = "123"),那么结果中不会出现所有 FooBar 怎么办?
  • @benjamin54 我认为你不能用“简单”的查询来做到这一点。我认为您需要使用聚合框架,但我不确定。也许你最好提出另一个问题......
  • 嘿,如果Foo 对象有一个 dateTime 属性,我想通过 dategreaterorequal 参数找到它,你将如何实现呢?这样做不起作用 -> var findFluent = collection.Find(Builders.Filter.ElemMatch( foo => foo.Bars, foobar => foobar.TimeCreate >= timeParam));
  • 如果我需要像这样比较任何整个子对象怎么办?就像想象将查询的最后一部分更改为 ... foobar => foobar.child == someobject)) 这可能吗?
猜你喜欢
  • 2020-08-08
  • 2017-02-26
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-10
  • 2021-11-03
  • 2016-11-16
相关资源
最近更新 更多