gpt4 book ai didi

c# - MongoDB C# 驱动程序 - 如何在 .NET 中对加入的集合强制执行投影?

转载 作者:行者123 更新时间:2023-12-05 05:04:40 42 4
gpt4 key购买 nike

代码如下:

ProjectionDefinition<Accountant> projDefAccountant = Builders<Accountant>.Projection
.Include(x => x.Id)
.Include(x => x.Name);

ProjectionDefinition<Client> projDefClient = Builders<Client>.Projection
.Include(c => c.Name)
.Include(c => c.Address)
.Include(c => c.Occupation);

IMongoCollection<Accountant> collection = mongoDatabase.GetCollection<Accountant>("accountants");
IMongoCollection<Client> foreignCollection = mongoDatabase.GetCollection<Client>("clients");

var results = collection.Aggregate()
.Project<Accountant>(projDefAccountant)
.Lookup<Accountant, Client, Accountant>(
foreignCollection: foreignCollection,
localField: ac => ac.BestClientsIds,
foreignField: c => c.Id,
@as: ac => ac.MyClients
).ToList().AsQueryable();

我可以使用第一个投影 "projDefAccountant" 来限制我想要从 "accountants" 集合中获取哪些字段。有没有办法在连接的 "clients" 集合上强制执行 "projDefClient" 投影,以便连接不会返回所有字段,而只返回 “projDefClient”?谢谢。

最佳答案

您可以使用 $lookup with custom pipeline您的聚合可能如下所示:

db.accountants.aggregate([
{ "$project" : { "_id" : 1, "Name" : 1, BestClientsIds: 1 } },
{
"$lookup" : {
"from" : "clients",
"let" : { "best_client_ids" : "$BestClientsIds" },
"pipeline" : [
{ "$match" : { "$expr" : { "$in" : [ "$_id", "$$best_client_ids"] } } },
{ "$project": { Name: 1, Address: 1, Occupation: 1} }
],
as: "MyClients"}
}
]);

Mongo Playground

在 C# 中,有一个重载版本的 .Lookup 允许您以几乎是强类型的方式运行该方法。这是签名:

IAggregateFluent<TNewResult> Lookup<TForeignDocument, TAsElement, TAs, TNewResult>(
IMongoCollection<TForeignDocument> foreignCollection,
BsonDocument let,
PipelineDefinition<TForeignDocument, TAsElement> lookupPipeline,
FieldDefinition<TNewResult, TAs> @as,
AggregateLookupOptions<TForeignDocument, TNewResult> options = null)
where TAs : IEnumerable<TAsElement>;

您可以修改 projDefAccountant 使其包含 BestClientsIds 字段:

ProjectionDefinition<Accountant> projDefAccountant = Builders<Accountant>.Projection
.Include(x => x.Id)
.Include(x => x.Name)
.Include(x => x.BestClientsIds);

然后将 let$match 阶段指定为 BsonDocument 更容易,但其余部分保持强类型:

var filter = new BsonDocumentFilterDefinition<Client>(BsonDocument.Parse("{ $expr: { $in: [ '$_id', '$$ids' ] } }"));

PipelineDefinition< Client, Client> pipeline = new PipelineStagePipelineDefinition<Client, Client>(
new IPipelineStageDefinition[]
{
PipelineStageDefinitionBuilder.Match(filter),
PipelineStageDefinitionBuilder.Project<Client, Client>(projDefClient),
});

ExpressionFieldDefinition<Accountant, Client[]> fieldDef
= new ExpressionFieldDefinition<Accountant, Client[]>(f => f.MyClients);

var letDef = BsonDocument.Parse("{ ids: '$BestClientsIds' }");


var results = collection.Aggregate()
.Project<Accountant>(projDefAccountant)
.Lookup<Client, Client, Client[], Accountant>(
foreignCollection: foreignCollection,
let: letDef,
lookupPipeline: pipeline,
@as: fieldDef
).ToList().AsQueryable();

关于c# - MongoDB C# 驱动程序 - 如何在 .NET 中对加入的集合强制执行投影?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60960388/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com