展开时的字段名称冲突(_id)

时间:2018-09-12 15:40:13

标签: c# mongodb subquery aggregation

我有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(); 

1 个答案:

答案 0 :(得分:0)

您可以使用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();