我正在嘗試使用 mongodb 聚合方法對資料進行分組。我不知道資料庫結構,但電子郵件列會在那里。在 DB 電子郵件列中可以保存任何名稱,如 gmail、mail 等。例如 test DB 如下所示。如果我們不知道資料庫中存在的名稱,如何按電子郵件列分組
{
"name": "stuv",
"email": "[email protected]",
"phone": "12345678990"
},
{
"name": "pqr",
"email": "[email protected]",
"phone": "9876543210"
},
{
"name": "xyz",
"email": "[email protected]",
"phone": "2345678901"
},
{
"name": "abc",
"email": "[email protected]",
"phone": "4567890123"
}
從上面的資料庫中,我想按未知列名電子郵件對資料進行分組,因此我正在展開資料并使用電子郵件正則運算式匹配值,并對資料進行分組并將根資料推送到 dups,如下所示。
db.test.aggregate([
{$project: {_id: 0}},
{$project: {data: { $objectToArray: "$$ROOT"}}},
{ $unwind: "$data"},
{$group: {_id: "$data.v",
dups:{ $push: "$data"},
count: { "$sum": 1 }
}},
{ $match: { "_id": /^\w ([\.-]?\w )*@\w ([\.-]?\w )*(\.\w{2,3}) $/ } },
])
在使用 unwind 后,從上面的聚合函式中,我沒有得到 dups 中的所有欄位(姓名、電話、電子郵件),而是只得到分組欄位,即分別以鍵和值的形式發送的電子郵件列,如下面的輸出所示。我想要像 email:[email protected] 這樣的輸出以及所有其他欄位,如預期的輸出結果所示。
我的輸出:
"result": [
{
"_id": "[email protected]",
"dups": [
{
"k": "email",
"v": "[email protected]"
},
{
"k": "email",
"v": "[email protected]"
}
],
"count": 2
},
{
"_id": "[email protected]",
"dups": [
{
"k": "email",
"v": "[email protected]"
},
{
"k": "email",
"v": "[email protected]"
}
],
"count": 2
}
]
預期輸出
"result": [
{
"_id": {
"email": "[email protected]"
},
"dups": [
{
"_id": "62af2c14e50225b659ab68a4",
"name": "pqr",
"email": "[email protected]",
"phone": "9876543210"
},
{
"_id": "62af2c14e50225b659ab68a6",
"name": "abc",
"email": "[email protected]",
"phone": "4567890123"
}
],
"count": 2
},
{
"_id": {
"email": "[email protected]"
},
"dups": [
{
"_id": "62af2c14e50225b659ab68a3",
"name": "stuv",
"email": "[email protected]",
"phone": "12345678990"
},
{
"_id": "62af2c14e50225b659ab68a5",
"name": "xyz",
"email": "[email protected]",
"phone": "2345678901"
}
],
"count": 2
}
]
請幫助我解決這個問題。
uj5u.com熱心網友回復:
編輯:一種選擇是保留當前資料及其鍵和值陣列,此處為mailData
. $regexMatch
然后我們可以使用和$reduce
在$group
步驟中使用它來提取電子郵件值作為_id
db.collection.aggregate([
{$project: {mailData: {$objectToArray: "$$ROOT"}, data: "$$ROOT"}},
{
$set: {
mailData: {
$first: {
$reduce: {
input: "$mailData",
initialValue: [],
in: {
$concatArrays: [
"$$value",
{
$cond: [
{
$regexMatch: {
input: {$toString: "$$this.v"},
regex: /^\w (?:[.-]\w )*@\w (?:[.-]\w )*\.\w{2,3}$/
}
},
["$$this.v"],
[]
]
}
]
}
}
}
}
}
},
{
$group: {
_id: "$mailData",
dups: {$push: "$data"},
count: {"$sum": 1}
}
}
])
看看它在操場上的例子是如何作業的
另一個選項類似于您的嘗試,但$regexMatch
之后使用和分組:
db.collection.aggregate([
{$project: {mailData: {$objectToArray: "$$ROOT"}, data: "$$ROOT"}},
{$unwind: "$mailData"},
{
$match: {
$expr: {
$eq: [
{$regexMatch: {
input: {$toString: "$mailData.v"},
regex: /^\w (?:[.-]\w )*@\w (?:[.-]\w )*\.\w{2,3}$/
}
}, true
]
}
}
},
{
$group: {
_id: "$mailData.v",
dups: {$push: "$data"},
count: {"$sum": 1}
}
}
])
看看它在操場上的例子是如何作業的 - 放松
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/493323.html