我想知道是否可以在單個findOneAndUdate()方法呼叫中實作以下問題。讓我們考慮這個集合條目:
[
{
"key": 1,
"logs": [
{
"app_logs": [
{
"stdout": "app_stdout_1",
"stderr": "app_stderr_1"
}
],
"syslog": "syslog_val1"
},
{
"app_logs": [
{
"stdout": "app_stdout_2",
"stderr": "app_stderr_2"
}
],
"syslog": "syslog_val2"
}
]
},
]
我需要將其他元素推送到“app_logs”陣列中,但只能在“logs”陣列的最后一個條目中。目前為了繞過這個問題,我按原樣獲取檔案,在應用程式中執行這樣的推送,然后使用findOneAndReplace()方法。雖然這可行,但我希望它可以通過單個 MongoDB 呼叫來實作。我嘗試了各種方法,如管道聚合、更新陣列過濾器等,但無法讓它們中的任何一個作業。還嘗試在線查找解決方案,閱讀檔案但仍然找不到任何成功解決的類似問題。
人們傾向于遇到的最常見的類似問題是在條件下更新嵌套陣列中的特定元素,這可以通過使用位置運算子來解決,例如:
findOneAndUpdate({
"key": 1,
"logs.syslog": "syslog_val1"
},
{
"$push": {
"logs.$.app_logs": {
"stdout": "app_stdout_new",
"stderr": "app_stderr_new"
}
}
})
在我的情況下,我想執行這樣的推送,不是針對“日志”陣列的特定元素,而是只針對最后一個。由于我已經在這個問題上花費了很多時間,這讓我想到它是否可以實作,或者當前 MongoDB 版本是否存在任何限制,這會使這種實作變得不可能。謝謝你的幫助。
uj5u.com熱心網友回復:
對于您的場景,通過使用聚合管道更新查詢來實作它。
$set- 獲取logsas的最后一個元素lastLog。$set2.1
$concatArrays- 將陣列與logs(最后一個檔案除外)的所有元素和 2.2 的結果合并。2.2
$mergeObjects- 將物件與 2.3 的結果合并lastLog,旨在覆寫該app_logs欄位。2.3 - 將陣列與新檔案
$mergeArrays合并(作為陣列)。lastLog.app_logs$unset- 洗掉lastLog欄位。
db.collection.update({
"key": 1,
"logs.syslog": "syslog_val1"
},
[
{
$set: {
"lastLog": {
$arrayElemAt: [
"$logs",
-1
]
}
}
},
{
$set: {
"logs": {
$concatArrays: [
{
$slice: [
"$logs",
{
$add: [
{
$size: "$logs"
},
-1
]
}
]
},
[
{
$mergeObjects: [
"$lastLog",
{
"app_logs": {
$concatArrays: [
"$lastLog.app_logs",
[
{
"stdout": "app_stdout_new",
"stderr": "app_stderr_new"
}
]
]
}
}
]
}
]
]
}
}
},
{
$unset: "lastLogs"
}
])
示例 Mongo Playground
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/457725.html
