簡體   English   中英

將值從舊字段遷移到 mongodb 數組中子文檔內的新字段

[英]Migrating a value from an old field to a new field inside subdocuments in an array for mongodb

我在 mongo 集合的每個文檔中都有一項任務,將值從一個字段遷移到另一個新字段。

數據最初外觀的示例:

{
    "_id" : ObjectId("5ec402eca370d5834f18b762"),
    "serial" : "SN12345678",
    "hostname" : "router1",
    "interfaces" : [
        {
            "name" : "eth0",
            "type" : "sfp",
            "connection": "isp"
            "ip" : "192.168.1.1/24",
            "gateway" : "192.168.1.254",
        },
        {
            "name" : "eth1",
            "type" : "copper",
            "connection": "switch"
        }
    ],
}
{
    "_id" : ObjectId("1vb402hnk370d9520d18b333"),
    "serial" : "SN87654321",
    "hostname" : "switch1",
    "interfaces" : [
        {
            "name" : "eth0",
            "type" : "copper",
            "connection": "pc"
        },
        {
            "name" : "eth1",
            "type" : "copper",
            "connection": "printer"
        }
    ],
}

我需要將值從“connection”字段移動到每個集合文檔中的“conenction_to”字段。 最終結果應如下所示:

{
    "_id" : ObjectId("5ec402eca370d5834f18b762"),
    "serial" : "SN12345678",
    "hostname" : "router1",
    "interfaces" : [
        {
            "name" : "eth0",
            "type" : "copper",
            "connection_to": {
                "device_type": "isp"
            }
            "ip" : "192.168.1.1/24",
            "gateway" : "192.168.1.254",
        },
        {
            "name" : "eth1",
            "type" : "copper",
            "connection_to": {
                "device_type": "switch"
            }
        }
    ],
}
{
    "_id" : ObjectId("1vb402hnk370d9520d18b333"),
    "serial" : "SN87654321",
    "hostname" : "switch1",
    "interfaces" : [
        {
            "name" : "eth0",
            "type" : "copper",
            "connection_to": {
                "device_type": "pc"
            }
        },
        {
            "name" : "eth1",
            "type" : "copper",
            "connection_to": {
                "device_type": "printer"
            }
        }
    ],
}

我有一個用 golang 編寫的微服務與 mongo 數據庫一起工作,遷移機制內部是使用 github.com/golang-migrate/migrate/ 包實現的(JSON 用作該包的請求源)。

我之前對數據庫沒有太多經驗,並且在處理 mongo 數組中的嵌套文檔時遇到了困難。 首先,我嘗試用通常的“更新”和“設置”來解決問題:

[
    {
        "update": "devices",
        "updates": [
            {
                "q": {"interfaces": {"$exists" : true}},
                "u": {
                    "$set": {
                        "interfaces.$[].connection_to": {
                            "device_type": "$connection"
                        }
                    }
                },
                "multi": true
            }
        ]
    }
]

...但我無法重用舊“連接”字段中的值。

我閱讀了文檔並發現必須使用聚合來重用字段值的信息。 我收到了這樣的請求:

[
    {
        "aggregate": "devices",
        "pipeline": [
            {
                "$match" : {
                    "interfaces" : { "$exists":true }
                }
            },
            {
                "$set":{
                    "interfaces": {
                        "$map":{
                            "input": "$interfaces",
                            "as": "interface",
                            "in": {
                                "name": "$$interface.name",
                                "type": "$$interface.type",
                                "ip": "$$interface.ip",
                                "gateway": "$$interface.gateway",
                                "connection_to": {
                                    "device_type": "$$interface.connection"
                                }
                            }

                        }
                    }
                }
            },
            {
                "$out": "devices"
            }
        ],
        "cursor": {}
    }
]

目前這個選項有效,但有一個大問題。 實際上,在每個文檔中,我都重新創建了“接口”字段,並且必須明確指定附加文檔的所有字段,否則只會有一個新字段。 如果將來文檔中出現新字段並且有可能忘記在遷移中指定新字段,那么這是一個危險的時刻。

我將非常感謝有關如何改進查詢的幫助和建議,以便在將數據遷移到新字段時不會丟失其余字段。

有一個答案。 $mergeObjects 的使用

[
    {
        "aggregate": "devices",
        "pipeline": [
            {
                "$match" : {
                    "interfaces" : { "$exists":true }
                }
            },
            {
                "$set":{
                    "interfaces": {
                        "$map":{
                            "input": "$interfaces",
                            "as": "interface",
                            "in": {
                                "$mergeObjects": [
                                    "$$interface",
                                    "connection_to": {
                                        "device_type": "$$interface.connection"
                                    }
                                ]
                            }
                        }
                    }
                }
            },
            {
                "$out": "devices"
            }
        ],
        "cursor": {}
    }
]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM