【问题标题】:Query a deeply nested object in arrays using MongoDB and C#使用 MongoDB 和 C# 在数组中查询深度嵌套的对象
【发布时间】:2020-03-18 21:14:58
【问题描述】:

我对 MongoDB 还很陌生,已经面临着艰巨的挑战。我正在尝试从带有对象的数组中的对象数组中获取一个元素(如果有意义的话)。这就是文档的外观以及我想要得到的内容:

所以基本上结构如下:

  • 选项菜单
    • 选项菜单主题
      • 选项菜单项

使用 MongoDB Compass 工具中的聚合管道工具获取我匹配的 OptionMenuItem 以将其拉出

[{
    $unwind: {
        path: '$subjects'
    }
}, {
    $unwind: {
        path: '$subjects.items'
    }
}, {
    $project: {
        _id: '$subjects.items._id',
        item: '$subjects.items'
    }
}, {
    $match: {
        _id: ObjectId('5e6eaef8ae35a418f4f6dbd4')
    }
}]

然后我尝试将其翻译成 C#,但没有成功,这是我所来的:

        var optionMenuItem = await collection.Aggregate()
           .Unwind<OptionMenu, OptionMenuSubject>(i => i.Subjects)
           .Unwind<OptionMenuSubject, OptionMenuItem>(i => i.Items)
           .Match(i => i.Id == id)
           .ToListAsync();

如果有人知道我做错了什么或如何解决这个问题,我将不胜感激:)

【问题讨论】:

    标签: c# mongodb mongodb-.net-driver


    【解决方案1】:

    这就是我最终解决它的方法。不是我最自豪的工作,因为它没有强类型,但它可以工作:

    var collection = Database.GetCollection<BsonDocument>(_collectionName);    
    var query = await collection.Aggregate()
                    .Match(i => i["subjects.items._id"] == ObjectId.Parse(id))
                    .Unwind(i => i["subjects"])
                    .Unwind(i => i["subjects.items"])
                    .Match(i => i["subjects.items._id"] == ObjectId.Parse(id))
                    .ReplaceRoot(i => i["subjects.items"])
                    .FirstOrDefaultAsync();
    

    【讨论】:

      【解决方案2】:

      展开未过滤的数据不是一个好主意,因为它会在 mongodb 内存中创建大量数据,并且您可能会达到 100mb 聚合管道的限制。所以尝试在展开之前总是过滤和缩小记录。我相信以下管道会提供您需要的结果:

      db.collection.aggregate([
          {
              $match: {
                  'subjects.items._id': ObjectId('5e6eaef8ae35a418f4f6dbd4')
              }
          },
          {
              $unwind: '$subjects'
          },
          {
              $unwind: '$subjects.items'
          },
          {
              $match: {
                  'subjects.items._id': ObjectId('5e6eaef8ae35a418f4f6dbd4')
              }
          },
          {
              $replaceWith: '$subjects.items'
          }
      ])
      

      这里有一个convenient way 来用 c# 执行这个管道。你可以阅读更多关于它是如何工作的here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-23
        • 2020-07-21
        • 2020-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-01
        相关资源
        最近更新 更多