如何在 C# 中的 MongoDB 查询中将 "aggregate" 与 "project" 一起使用?
How to use "aggregate" with "project" in MongoDB query in C#?
环境:
MongoDB.Driver (2.8.1);
Microsoft.NETCore.App (3.0.0-preview7-27912-14);
语言:C#
我在 MongoDB 中有以下存储结构,在一个名为:"Revendas":
的集合中
...
{
"_id" : ObjectId("5cd0825f92225e4f1179f3b8"),
"Codigo" : NumberLong(0),
"Nome" : "Revenda com dois clientes",
"CPF" : "string",
"CNPJ" : "string",
"Clientes" : [
{
"Codigo" : "1",
"Nome" : "Primeiro cliente da revenda 5cd0825f92225e4f1179f3b8",
"CPF" : "string",
"CNPJ" : "string",
"Tokens" : [
{
"Token" : "bd2b0f0734b3977ebfd56b6965fbdf9bff17f1e6",
"Geracao" : ISODate("2019-05-03T17:27:30.678-03:00"),
"Revogacao" : ISODate("2019-05-03T17:28:58.858-03:00")
}
]
},
{
/*This is the block I need to return*/
"Codigo" : "2",
"Nome" : "Segundo cliente da revenda 5cd0825f92225e4f1179f3b8",
"CPF" : "string",
"CNPJ" : "string",
"Tokens" : [
{
/* This is the field where I will do the research */
"Token" : "671bcaf806405e5d55419746a1b320cc729558fb",
"Geracao" : ISODate("2019-05-06T09:29:07.928-03:00"),
"Revogacao" : ISODate("2022-05-06T09:29:07.928-03:00")
}
]
}
]
}
...
我想搜索客户端令牌集合,return 只搜索回答查询的客户端。
我能够直接在 mongodb:
中执行查询
db.Revendas.aggregate([
{ $unwind :'$Clientes'},
{ $match : {'Clientes.Tokens.Token': '671bcaf806405e5d55419746a1b320cc729558fb' }},
{
$project : {
Codigo: "$Clientes.Codigo",
Nome : '$Clientes.Nome',
CNPJ : '$Clientes.CNPJ',
CPF: '$Clientes.CPF',
Tokens : '$Clientes.Tokens'
}
}
])
上次查询return我需要的数据:
{
"_id" : ObjectId("5cd0825f92225e4f1179f3b8"),
"Codigo" : "2",
"Nome" : "Segundo cliente da revenda 5cd0825f92225e4f1179f3b8",
"CNPJ" : "string",
"CPF" : "string",
"Tokens" : [
{
"Token" : "671bcaf806405e5d55419746a1b320cc729558fb",
"Geracao" : ISODate("2019-05-06T09:29:07.928-03:00"),
"Revogacao" : ISODate("2022-05-06T09:29:07.928-03:00")
}
]
}
问题是,如何将此查询转换为 C# mongodb 驱动程序?
我的尝试是:
string tokenpesquisa = "";
var agg = Database.GetCollection<RevendaCliente>("{'Clientes.Tokens.Token': '" + tokenpesquisa + "'}").Aggregate();
var project = agg.Project(o => new {
Codigo = o.Codigo,
Nome = o.Nome,
CNPJ = o.CNPJ,
CPF = o.CPF,
Tokens = o.Tokens
});
var result = project.ToListAsync().Result;
但数据未按预期return编辑。
以下是用户@mickl 建议的解决我问题的代码片段:
CollRevendas = Database.GetCollection<Revenda>("Revendas");
var query = CollRevendas.Aggregate()
.Unwind("Clientes")
.Match(new BsonDocument() { { "Clientes.Tokens.Token", "" + tokenpesquisa + "" } })
.Project<RevendaCliente>(new BsonDocument()
{
{ "_id", 0 },
{ "Codigo", "$Clientes.Codigo" },
{ "Nome", "$Clientes.Nome" },
{ "CNPJ", "$Clientes.CNPJ" },
{ "CPF", "$Clientes.CPF" },
{ "Tokens", "$Clientes.Tokens" }
});
var doc = query.First();
return doc;
通用方法 GetCollection<T>
将集合名称作为第一个参数。这里最简单的方法是对代表 MongoDB 文档的 BsonDocument
类型进行操作,稍后可以将其反序列化为您的类型:
var col = database.GetCollection<BsonDocument>("Revendas");
var query = col.Aggregate()
.Unwind("Clientes")
.Match(new BsonDocument(){ { "Clientes.Tokens.Token", "671bcaf806405e5d55419746a1b320cc729558fb" } })
.Project(new BsonDocument()
{
{ "Codigo", "$Clientes.Codigo" },
{ "Nome", "$Clientes.Nome" },
{ "CNPJ", "$Clientes.CNPJ" },
{ "CPF", "$Clientes.CPF" },
{ "Tokens", "$Clientes.Tokens" }
});
var doc = query.First();
您还可以通过引入表示结果的类型来转换聚合结果:
public class Model
{
public ObjectId Id { get; set; }
public string Codigo { get; set; }
public string Nome { get; set; }
public string CNPJ { get; set; }
public string CPF { get; set; }
public TokenModel[] Tokens { get; set; }
}
public class TokenModel
{
public string Token { get; set; }
public DateTime Geracao { get; set; }
public DateTime Revogacao { get; set; }
}
和运行 Project
的通用版本:
.Project<Model>(new BsonDocument()
{
{ "Codigo", "$Clientes.Codigo" },
{ "Nome", "$Clientes.Nome" },
{ "CNPJ", "$Clientes.CNPJ" },
{ "CPF", "$Clientes.CPF" },
{ "Tokens", "$Clientes.Tokens" }
});
环境:
MongoDB.Driver (2.8.1);
Microsoft.NETCore.App (3.0.0-preview7-27912-14);
语言:C#
我在 MongoDB 中有以下存储结构,在一个名为:"Revendas":
的集合中...
{
"_id" : ObjectId("5cd0825f92225e4f1179f3b8"),
"Codigo" : NumberLong(0),
"Nome" : "Revenda com dois clientes",
"CPF" : "string",
"CNPJ" : "string",
"Clientes" : [
{
"Codigo" : "1",
"Nome" : "Primeiro cliente da revenda 5cd0825f92225e4f1179f3b8",
"CPF" : "string",
"CNPJ" : "string",
"Tokens" : [
{
"Token" : "bd2b0f0734b3977ebfd56b6965fbdf9bff17f1e6",
"Geracao" : ISODate("2019-05-03T17:27:30.678-03:00"),
"Revogacao" : ISODate("2019-05-03T17:28:58.858-03:00")
}
]
},
{
/*This is the block I need to return*/
"Codigo" : "2",
"Nome" : "Segundo cliente da revenda 5cd0825f92225e4f1179f3b8",
"CPF" : "string",
"CNPJ" : "string",
"Tokens" : [
{
/* This is the field where I will do the research */
"Token" : "671bcaf806405e5d55419746a1b320cc729558fb",
"Geracao" : ISODate("2019-05-06T09:29:07.928-03:00"),
"Revogacao" : ISODate("2022-05-06T09:29:07.928-03:00")
}
]
}
]
}
...
我想搜索客户端令牌集合,return 只搜索回答查询的客户端。 我能够直接在 mongodb:
中执行查询db.Revendas.aggregate([
{ $unwind :'$Clientes'},
{ $match : {'Clientes.Tokens.Token': '671bcaf806405e5d55419746a1b320cc729558fb' }},
{
$project : {
Codigo: "$Clientes.Codigo",
Nome : '$Clientes.Nome',
CNPJ : '$Clientes.CNPJ',
CPF: '$Clientes.CPF',
Tokens : '$Clientes.Tokens'
}
}
])
上次查询return我需要的数据:
{
"_id" : ObjectId("5cd0825f92225e4f1179f3b8"),
"Codigo" : "2",
"Nome" : "Segundo cliente da revenda 5cd0825f92225e4f1179f3b8",
"CNPJ" : "string",
"CPF" : "string",
"Tokens" : [
{
"Token" : "671bcaf806405e5d55419746a1b320cc729558fb",
"Geracao" : ISODate("2019-05-06T09:29:07.928-03:00"),
"Revogacao" : ISODate("2022-05-06T09:29:07.928-03:00")
}
]
}
问题是,如何将此查询转换为 C# mongodb 驱动程序?
我的尝试是:
string tokenpesquisa = "";
var agg = Database.GetCollection<RevendaCliente>("{'Clientes.Tokens.Token': '" + tokenpesquisa + "'}").Aggregate();
var project = agg.Project(o => new {
Codigo = o.Codigo,
Nome = o.Nome,
CNPJ = o.CNPJ,
CPF = o.CPF,
Tokens = o.Tokens
});
var result = project.ToListAsync().Result;
但数据未按预期return编辑。
以下是用户@mickl 建议的解决我问题的代码片段:
CollRevendas = Database.GetCollection<Revenda>("Revendas");
var query = CollRevendas.Aggregate()
.Unwind("Clientes")
.Match(new BsonDocument() { { "Clientes.Tokens.Token", "" + tokenpesquisa + "" } })
.Project<RevendaCliente>(new BsonDocument()
{
{ "_id", 0 },
{ "Codigo", "$Clientes.Codigo" },
{ "Nome", "$Clientes.Nome" },
{ "CNPJ", "$Clientes.CNPJ" },
{ "CPF", "$Clientes.CPF" },
{ "Tokens", "$Clientes.Tokens" }
});
var doc = query.First();
return doc;
通用方法 GetCollection<T>
将集合名称作为第一个参数。这里最简单的方法是对代表 MongoDB 文档的 BsonDocument
类型进行操作,稍后可以将其反序列化为您的类型:
var col = database.GetCollection<BsonDocument>("Revendas");
var query = col.Aggregate()
.Unwind("Clientes")
.Match(new BsonDocument(){ { "Clientes.Tokens.Token", "671bcaf806405e5d55419746a1b320cc729558fb" } })
.Project(new BsonDocument()
{
{ "Codigo", "$Clientes.Codigo" },
{ "Nome", "$Clientes.Nome" },
{ "CNPJ", "$Clientes.CNPJ" },
{ "CPF", "$Clientes.CPF" },
{ "Tokens", "$Clientes.Tokens" }
});
var doc = query.First();
您还可以通过引入表示结果的类型来转换聚合结果:
public class Model
{
public ObjectId Id { get; set; }
public string Codigo { get; set; }
public string Nome { get; set; }
public string CNPJ { get; set; }
public string CPF { get; set; }
public TokenModel[] Tokens { get; set; }
}
public class TokenModel
{
public string Token { get; set; }
public DateTime Geracao { get; set; }
public DateTime Revogacao { get; set; }
}
和运行 Project
的通用版本:
.Project<Model>(new BsonDocument()
{
{ "Codigo", "$Clientes.Codigo" },
{ "Nome", "$Clientes.Nome" },
{ "CNPJ", "$Clientes.CNPJ" },
{ "CPF", "$Clientes.CPF" },
{ "Tokens", "$Clientes.Tokens" }
});