带有条件group by语句的MongoDB查询

带有条件group by语句的MongoDB查询,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我需要从mongoDB的数据库中导出客户记录。导出的客户记录不应具有重复的值。“firstName+lastName+code”是对记录进行重复数据消除的键,如果数据库中存在两条具有相同键的记录,则我需要优先选择值为非电子邮件的源字段 客户(id,firstName,lastName,code,source)集合就是这个 如果有3条记录具有相同的唯一键和3个不同的源,则我需要在2个源(电视、互联网)中只选择一条记录{或者如果有n个源,我只需要一条记录}不使用“电子邮件”(因为只有一条记录具有唯一

我需要从mongoDB的数据库中导出客户记录。导出的客户记录不应具有重复的值。“firstName+lastName+code”是对记录进行重复数据消除的键,如果数据库中存在两条具有相同键的记录,则我需要优先选择值为非电子邮件的源字段

客户(
id,firstName,lastName,code,source
)集合就是这个

如果有3条记录具有相同的唯一键和3个不同的源,则我需要在2个源(电视、互联网)中只选择一条记录{或者如果有n个源,我只需要一条记录}不使用“电子邮件”(因为只有一条记录具有唯一键,且源为电子邮件时,将选择电子邮件) 查询使用:

db.customer.aggregate([
    {
        "$match": {
            "active": true,
            "dealerCode": { "$in": ["111391"] },
            "source": { "$in": ["email", "TV", "internet"] }
        }
    },
    {
        $group: {
            "_id": {
                "firstName": "$personalInfo.firstName",
                "lastName": "$personalInfo.lastName",
                "code": "$vehicle.code"
            },
            "source": {
                $addToSet: { "source": "$source" }
            }
        }
    },
    {
        $redact:
        {
            $cond: [
                { $eq: [{ $ifNull: ["$source", "other"] }, "email"] },
                "$$PRUNE",
                "$$DESCEND"
            ]
        }
    },
    {
        $project:
        {
            "source":
            {
                $map:
                {
                    "input": {
                        $cond: [
                            { $eq: [{ $size: "$source" }, 0] },
                            [{ "source": "email" }],
                            "$source"
                        ]
                    },
                    "as": "inp",
                    "in": "$$inp.source"
                }
            },
            "record": { "_id": 1 }
        }
    }
])
样本输出:

{ "_id" : { "firstName" : "sGI6YaJ36WRfI4xuJQzI7A==", "lastName" : "99eQ7i+uTOqO8X+IPW+NOA==", "code" : "1GTHK23688F113955" }, "source" : ["internet"] }
{ "_id" : { "firstName" : "WYDROTF/9vs9O7XhdIKd5Q==", "lastName" : "BM18Uq/ltcbdx0UJOXh7Sw==", "code" : "1G4GE5GV5AF180133" }, "source" : ["internet"] }
{ "_id" : { "firstName" : "id+U2gYNHQaNQRWXpe34MA==", "lastName" : "AIs1G33QnH9RB0nupJEvjw==", "code" : "1G4GE5EV0AF177966" }, "source" : ["internet"] }
{ "_id" : { "firstName" : "qhreJVuUA5l8lnBPVhMAdw==", "lastName" : "petb0Qx3YPfebSioY0wL9w==", "code" : "1G1AL55F277253143" }, "source" : ["TV"] }
{ "_id" : { "firstName" : "qhreJVuUA5l8lnBPVhMAdw==", "lastName" : "6LB/NmhbfqTagbOnHFGoog==", "code" : "1GCVKREC0EZ168134" }, "source" : ["TV", "internet"] }

此查询存在问题,请建议:(

您的代码不起作用,因为它不是累加器运算符。只有累加器运算符才能在
$group
阶段中使用

假设您的记录中包含的
source
的可能值不超过两个,您可以添加一个有条件的
$project
阶段,并将
$group
阶段修改为

代码:

db.customer.aggregate([
{
$group:{
“_id”:{
“id”:“$id”,
“firstName”:“$firstName”,
“lastName”:“$lastName”,
“代码”:“$code”
},
“sourceA”:{$first:$source},
“sourceB”:{$last:$source}
}
},
{
$项目:{
“来源”:{
$cond:[
{$eq:[“$sourceA”,“email”]},
“$sourceB”,
“$sourceA”
]
}
}
}
])
如果source可能有两个以上的值,则可以执行以下操作:

  • id
    firstName
    lastName
    code
    进行分组 使用运算符指定
    的唯一值
  • 用于仅保留
    电子邮件
    以外的值
  • Project
    必填字段,如果
    source
    数组为空(所有元素都已删除),请添加一个 值
    向其发送电子邮件
  • 展开源字段,将其列为字段而不是数组。
    (可选)
代码:

db.customer.aggregate([
{
$group:{
“_id”:{
“id”:“$id”,
“firstName”:“$firstName”,
“lastName”:“$lastName”,
“代码”:“$code”
},
“sourceArr”:{$addToSet:{“source”:“$source”}
}
},
{
$redact:{
$cond:[
{$eq:[{$ifNull:[“$source”,“other”]},email“]},
“$$PRUNE”,
“$$下降”
]
}
},
{
$项目:{
“来源”:{
$map:{
“输入”:
{
$cond:[
{$eq:[{$size:$sourceArr},0]},
[{“来源”:“项目”}],
“$sourceArr”]
},
“as”:“inp”,
“在”:“$$inp.source”
}
}
}
}
])

您的代码无效,因为它不是累加器运算符。只有累加器运算符才能在
$group
阶段中使用

假设您的记录中包含的
source
的可能值不超过两个,您可以添加一个有条件的
$project
阶段,并将
$group
阶段修改为

代码:

db.customer.aggregate([
{
$group:{
“_id”:{
“id”:“$id”,
“firstName”:“$firstName”,
“lastName”:“$lastName”,
“代码”:“$code”
},
“sourceA”:{$first:$source},
“sourceB”:{$last:$source}
}
},
{
$项目:{
“来源”:{
$cond:[
{$eq:[“$sourceA”,“email”]},
“$sourceB”,
“$sourceA”
]
}
}
}
])
如果source可能有两个以上的值,则可以执行以下操作:

  • id
    firstName
    lastName
    code
    进行分组 使用运算符指定
    的唯一值
  • 用于仅保留
    电子邮件
    以外的值
  • Project
    必填字段,如果
    source
    数组为空(所有元素都已删除),请添加一个 值
    向其发送电子邮件
  • 展开源字段,将其列为字段而不是数组。
    (可选)
代码:

db.customer.aggregate([
{
$group:{
“_id”:{
“id”:“$id”,
“firstName”:“$firstName”,
“lastName”:“$lastName”,
“代码”:“$code”
},
“sourceArr”:{$addToSet:{“source”:“$source”}
}
},
{
$redact:{
$cond:[