如何在C#中的MongoDB查询中将“聚合”与“项目”一起使用?

时间:2019-08-26 19:09:29

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

环境:

MongoDB.Driver(2.8.1);

Microsoft.NETCore.App(3.0.0-preview7-27912-14);

语言:C#

我在MongoDB中具有以下存储结构,名为Colletion:“ 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")
                }
            ]
        }
    ]
}
...

我想搜索客户端令牌集合并仅返回回答查询的客户端。 我能够直接在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'       
        } 
    }
])

上一个查询返回我需要的数据

{
    "_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;

但是数据未按预期返回。


以下是用户@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;

1 个答案:

答案 0 :(得分:1)

通用方法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" }
    });