【问题标题】:Field name collision (_id) when doing unwind展开时字段名称冲突 (_id)
【发布时间】:2019-02-17 07:39:10
【问题描述】:

我有 mongo 集合,其中的文档如下所示:

{ 
  _id: "384iojweiu83ur8233uui",
  name: "Jack",
  friends: [
    { 
      _id: "384798237498234",
      name: "Alfred"
    },
    { 
      _id: "384798234749829",
      name: "Deborah"
    }
  ]
}

我想检索一个给定_id 的人,并且只有一个给朋友_id 的朋友。像这样的:

{ 
  _id: "384iojweiu83ur8233uui",
  name: "Jack",
  friend_id: "384798237498234",
  friend_name: "Alfred"  
}

我试图通过 c# mongo 驱动程序中的unwind 方法这样做,但是我被困在这一点上。

var people = await collection.Aggregate()
    .Unwind<Person, PersonWithFriend>(_ => _.friends } )
    .Match( _ => _.Id == new ObjectId("5b646004b5728100042dd358"))
    .ToListAsync(); 

【问题讨论】:

    标签: c# mongodb subquery aggregation


    【解决方案1】:

    您可以使用positional operator $ 仅返回数组的第一个匹配元素:

    db.users.find(
        { "friends._id": "384798237498234" },
        { "name": 1, "friends.$": 1 }
    );
    

    或者,如果您需要在friends 子文档上匹配多个条件,您可以使用$elemMatch

    db.users.find(
        { "friends":  { 
            "$elemMatch": { "id": "384798237498234",  "somethingElse": "..." }
        }},
        { "name": 1, "friends.$": 1 }
    );
    

    这将生成带有单个元素的friends 数组的结果:

    { 
        _id: "384iojweiu83ur8233uui",
        name: "Jack",
        friends: [{
            id: "384798237498234",
            name: "Alfred"  
        }]
    }
    

    如果您确实需要在结果对象的根目录中包含朋友的idname,那么您可以使用聚合框架做同样的事情并在最后添加一个展开步骤。

    在 C# 中应该是这样的:

    users
        .Find(user => user.friends.Any(friend => friend.id == "384798237498234"))
        .Project(projection)
        .ToListAsync();
    

    【讨论】:

    • 对不起@Danziger 我在问如何在 C# MongoDB Driver Pipeline 中做到这一点,而不是纯 mongodb js。不过谢谢。我将尝试使用 Bson 文档查询方法。
    猜你喜欢
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-27
    • 2017-10-31
    • 2023-02-10
    • 1970-01-01
    • 2016-09-25
    相关资源
    最近更新 更多