如何使用 Linq 在 Mongo C# 2.2 驱动程序中查询嵌套列表?

Hao*_*Hao 5 c# linq mongodb

如何使用 Linq 进行聚合查询。我知道有一个AsQueryable()接口。但是当我进行聚合时似乎会抛出错误。

如果我有一个名为personstore data的集合,如下所示:

  {
    "Name": "Punny",
    "Interests": [
      1,
      2
    ]
  }
Run Code Online (Sandbox Code Playgroud)

另一个名为interests存储数据的集合是这样的:

  {
    "_id":1,
    "name":"music"
  },
  {
    "_id":2,
    "name":"read"
  }
Run Code Online (Sandbox Code Playgroud)

我想得到这样的东西:

  {
    "Name": "Punny",
    "Interests": [
      "music",
      "read"
    ]
  }
Run Code Online (Sandbox Code Playgroud)

我怎样才能通过 Linq to with 实现这一点AsQueryable?我试过这个:

_context.People.AsQueryable()
    .Select(p => new
    {
      Name = p.Name,
      Interests = p.InterestingIds
       .Join(_context.Interests.AsQueryable(),
        per => per,
        i => i.Id,
        (per, i) => new {i.Name})
    }).ToList();
Run Code Online (Sandbox Code Playgroud)

它抛出一个 System.NotSupportedException

System.NotSupportedException :表达式树 {document}{InterestingIds}.Join([FunnyMongoBlog.interest], per => per, i => i.Id, (per, i ) => new <>f__AnonymousType1`1(Name = i.Name))。

我尝试了两次数据库之旅:

      var person = _context.People.AsQueryable()
    .Single(p => p.Name == "Punny");
  var ids = person.InterestingIds;
  var query = _context.Interests.AsQueryable()
    .Where(i => ids.Contains(i.Id)).ToList();
  var result = new
  {
    person.Name,
    Interest = query
  };
Run Code Online (Sandbox Code Playgroud)

这是有效的,但我想知道我们是否可以一次完成,以便数据库可以处理聚合。

pro*_*r79 0

您可以在聚合框架中执行此操作,但我建议使用 mongoDB 中 subDocumnets 的功能并将这些元素完全嵌入到主文档中。换句话说,我们需要从关系思维转向文档思维。

我建议的物体形状:

{
    "Name" : "Punny",
    "Interests" : [{
            "_id" : 1,
            "name" : "music"
        }, {
            "_id" : 2,
            "name" : "read"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

在 C# 代码中

class MyClass {
    public string Name;
    public List < Interest > Interests;
}

class Interest {
    public int Id;
    public string Name;
}
Run Code Online (Sandbox Code Playgroud)

现在请找到所请求的转换所需的 bson 文档:

db.col.aggregate([{
            $unwind : "$Interests"
        }, {
            $lookup : {
                from : "interests",
                localField : "Interests",
                foreignField : "_id",
                as : "interest"
            }
        }, {
            // now we need to reshape document
            $project : {
                _id : 1,
                Name : 1,
                Interests : "$interest.name"
            }
        },
        //group documents back
        {
            $group : {
                _id : {
                    id : "$_id",
                    name : "$Name"
                },
                Interests : {
                    $push : "$Interests"
                }
            }
        }, {
            //final reshape
            _id : "$_id.id",
            Name : "$_id.name",
            Interests : 1
        }
    ])
Run Code Online (Sandbox Code Playgroud)

并决定嵌入是否值得一试:-)

有什么意见欢迎留言!