我需要从mongoDB数据库导出客户记录。导出的客户记录不应具有重复的值。 “firstName+lastName+code”是对记录进行重复删除的关键,如果数据库中存在两条具有相同键的记录,那么我需要优先考虑具有电子邮件以外值的源字段。
客户 (id,firstName,lastName,code,source
) 集合是这样的。
如果有 3 条记录具有相同的唯一键和 3 个不同的来源,那么我只需要在 2 个来源(电视、互联网)之间选择一条记录{或者如果有 n 个来源,我只需要一条记录}不与“电子邮件”(因为当只有一条记录具有唯一 key 并且来源是电子邮件时,将选择电子邮件) 查询使用:
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"] }
此查询有问题,请提出建议:(
最佳答案
您的代码不起作用,因为 $cond不是累加器运算符。仅these累加器运算符,可以在 $group
阶段使用。
假设您的记录包含不超过两个可能的 source
值(正如您在问题中提到的那样),您可以添加条件 $project
阶段并将 $group
阶段修改为,
代码:
db.customer.aggregate([
{
$group: {
"_id": {
"id": "$id",
"firstName": "$firstName",
"lastName": "$lastName",
"code": "$code"
},
"sourceA": { $first: "$source" },
"sourceB": { $last: "$source" }
}
},
{
$project: {
"source": {
$cond: [
{ $eq: ["$sourceA", "email"] },
"$sourceB",
"$sourceA"
]
}
}
}
])
如果源的可能值超过两个,那么您可以执行以下操作:
按
。积累id
、firstName
、lastName
和code
分组source
的唯一值,使用 $addToSet运算符。- 使用$redact仅保留
email
以外的值。 Project
必填字段,如果source
数组为空(所有元素已被删除),则添加一个 值email
给它。展开
源字段将其列为字段而不是数组。 (可选)
代码:
db.customer.aggregate([
{
$group: {
"_id": {
"id": "$id",
"firstName": "$firstName",
"lastName": "$lastName",
"code": "$code"
},
"sourceArr": { $addToSet: { "source": "$source" } }
}
},
{
$redact: {
$cond: [
{ $eq: [{ $ifNull: ["$source", "other"] }, "email"] },
"$$PRUNE",
"$$DESCEND"
]
}
},
{
$project: {
"source": {
$map: {
"input":
{
$cond: [
{ $eq: [{ $size: "$sourceArr" }, 0] },
[{ "source": "item" }],
"$sourceArr"]
},
"as": "inp",
"in": "$$inp.source"
}
}
}
}
])
关于带有条件group by语句的MongoDB查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28229496/