如何在mongodb中嵌套的嵌套文档进行迭代?

时间:2018-10-19 13:32:55

标签: json mongodb coldfusion

假设我有一个这样的文档结构:

{
    "product123_types": {
        "type_1": {
            "settings": {
                "name": "something",
                "success": "600,400,500,800"
            }
        }
    },
    "product345_types": {
        "type_1": {
            "settings": {
                "name": "something",
                "success": "500,400"
            }
        },
        "type_2": {
            "settings": {
                "name": "another one",
                "success": "500,800,700"
            }
        }
    }
}

如何从所有success条目中提取type值? product值将始终具有相同的架构,因此我想到了一个通配符来遍历所有products,但我不知道该怎么做。

最终目标是根据另一个查询表将success值转换为不同的值。它们之间用逗号分隔,这增加了另一个难度,但是如果我至少可以深入了解每种产品每种类型的所有成功值,那将是一个好的开始。

编辑:我本来希望通过Robo 3T或类似软件获得成功值,但是ColdFusion解决方案也可以使用。

1 个答案:

答案 0 :(得分:1)

ColdFusion解决方案

我已经在代码中为您添加了注释。

<cfscript>

    docFromDB = '{
        "product123_types": {
            "type_1": {
                "settings": {
                    "name": "something",
                    "success": "600,400,500,800"
                }
            }
        },
        "product345_types": {
            "type_1": {
                "settings": {
                    "name": "something",
                    "success": "500,400"
                }
            },
            "type_2": {
                "settings": {
                    "name": "another one",
                    "success": "500,800,700"
                }
            }
        }
    }'; // assuming you are fetching the JSON as string from the database

    // deserialize JSON string from database
    docFromDB = deserializeJSON(docFromDB);

    // iterate over each entry in the JSON
    for (key in docFromDB) {

        // skip all keys that do not match our pattern "productN_types"
        if (!reFind("^product[0-9]+_types$", key)) {
            continue;
        }

        // alias to reference the "productN_types" node
        productNode = docFromDB[key];

        // iterate over each entry in the "productN_types" node
        for (key in productNode) {

            // skip all keys that do not match our pattern "type_N"
            if (!reFind("^type_[0-9]+$", key)) {
                break;
            }

            // alias to reference the "type_N" node in the "productN_types" node
            typeNode = productNode[key];

            // skip node if there is no "settings" key in it
            if (!structKeyExists(typeNode, "settings")) {
                break;
            }

            // alias to reference the "settings" node in the "type_N" node of the "productN_types" node
            settingsNode = typeNode["settings"];

            // skip node if there is no "success" key in it
            if (!structKeyExists(settingsNode, "success")) {
                break;
            }

            // success values as "list" (comma separated)
            successValueList = settingsNode["success"];

            // success values as "array"
            successValueArray = listToArray(successValueList); // exactly what String.split(',') in JS does

            // iterate over each success value (we are using "i" to reference the entry later)
            i = 1;
            for (successValue in successValueArray) {

                // do your actual lookup, I'm just mocking something here
                if (successValue == "400") {

                    // we are using the current index "i" to overwrite the array value,
                    // because "successValue" is just a flat copy here
                    successValueArray[i] = "fourhundred";
                }

                i++;
            }

            // write back your modified success values,
            // "settingsNode" is a reference, so we can simply overwrite it
            settingsNode["success"] = arrayToList(successValueArray); // exactly what String.join(',') in JS does
        }
    }

    // your result
    writeDump(docFromDB);

</cfscript>