賞金將在 3 天后到期。此問題的答案有資格獲得 200聲望賞金。 GMe正在從有信譽的來源尋找答案。
我正在嘗試更新檔案值,如果它們已經存在于集合中,如果它們對于特定物件鍵具有相同的值。
例如,我有以下檔案 -
{ eventType: "A", browsers: [ { name: "Chrome", count: 10 } ]}
{ eventType: "B", browsers: [ { name: "Chrome", count: 2 } ]}
{ eventType: "A", browsers: [ { name: "Chrome", count: 5 }, { name: "Safari", count: 8 } ]}
最后,我希望集合按事件型別合并檔案,并按瀏覽器名稱值合并瀏覽器聚合(在下面的示例中,“Chrome”計數合并為 15);如果值不存在,則將新物件添加到 browsers 陣列(在下面的示例中,將“Safari”物件添加到現有瀏覽器聚合中):
{ eventType: "A", browsers: [ { name: "Chrome", count: 15 }, { name: "Safari", count: 8 } ]}
{ eventType: "B", browsers: [ { name: "Chrome", count: 2 } ]}
如果需要,我想使用以下查詢來更新和插入新檔案,但我不確定如何進行瀏覽器聚合。
const doc = { eventType: "A", browsers: [ { name: "Chrome", count: 5 }, { name: "Safari", count: 8 } ]}
collection.findOneAndUpdate({
eventType: doc.eventType
}, {
// What to do in here?
}, {
upsert: true,
new: true
})
是否有任何選項可以使用自定義函式,例如$accumulator在 collection.aggregate 用例中?
PS - 我在這段代碼中使用貓鼬
uj5u.com熱心網友回復:
不可能在一個陳述句中執行此操作,因為您的目標是按 eventType 將檔案收集到一組新檔案中,但是您可以通過合并的聚合完成大部分作業:
[{$unwind: {
path: '$browsers',
includeArrayIndex: 'b',
preserveNullAndEmptyArrays: true
}}, {$group: {
_id: '$eventType',
eventType: {
$first: '$eventType'
},
browsers: {
$addToSet: '$browsers'
}
}}, {$addFields: {
grouped: 1
}}, {$merge: {
into: 'so_example',
on: '_id',
whenMatched: 'replace',
whenNotMatched: 'discard'
}}]
這將需要第二個程序來 a) 洗掉未合并的檔案,并減少瀏覽器陣列,以便每個瀏覽器都有計數的總和。
uj5u.com熱心網友回復:
更新
創建一個包含所有鍵及其資料的組合物件,后跟多個組以計算出現次數。
轉換回單個關鍵欄位并使用更新資料的最后一步。
這里的作業示例 - https://mongoplayground.net/p/0ICHoflOke4
db.collectionname.aggregate([
{
"$project": {
"eventType": 1,
"categories": {
"$objectToArray": {
"$mergeObjects": [
{
"browsers": "$browsers"
},
{
"os": "$os"
}
]
}
}
}
},
{
"$unwind": "$categories"
},
{
"$unwind": "$categories.v"
},
{
"$group": {
"_id": {
"eventType": "$eventType",
"categoryType": "$categories.k",
"name": "$categories.v.name"
},
"count": {
"$sum": "$categories.v.count"
}
}
},
{
"$group": {
"_id": {
"eventType": "$_id.eventType",
"categoryType": "$_id.categoryType"
},
"category": {
"$push": {
"name": "$_id.name",
"count": "$count"
}
}
}
},
{
"$group": {
"_id": "$_id.eventType",
"categories": {
"$mergeObjects": {
"$arrayToObject": [
[
[
"$_id.categoryType",
"$category"
]
]
]
}
}
}
},
{
"$set": {
"eventType": "$_id"
}
},
{
"$project": {
"_id": 0
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$categories",
"$$ROOT"
]
}
}
},
{
"$project": {
"categories": 0
}
},
{
"$out": "collectionname"
}
])
您可以使用 $out 聚合運算子來聚合和覆寫包含更新資料的集合。
這里的作業示例 - https://mongoplayground.net/p/OsY3PgiVIfE
db.collectionname.aggregate([
{
"$unwind": "$browsers"
},
{
"$group": {
"_id": {
"eventType": "$eventType",
"name": "$browsers.name"
},
"count": {
"$sum": "$browsers.count"
}
}
},
{
"$group": {
"_id": "$_id.eventType",
"browsers": {
"$push": {
"name": "$_id.name",
"count": "$count"
}
}
}
},
{
"$set": {
"eventType": "$_id"
}
},
{
"$project": {
"_id": 0
}
},
{
"$out": "collectionname"
}
])
uj5u.com熱心網友回復:
顯然,不可能在單個原子查詢中做這樣的事情。我通過更改架構“解決”了它,因此鍵將是動態的,例如
{
browsers: {
Chrome: {
count: 15
}
}
}
通過這個實作,我update根據必須插入的新檔案動態構建 findOneAndUpdate 的部分。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/465395.html
上一篇:如何“加入”或填充陣列
