纯javascript(es2015)函数从树json结构中提取子

时间:2017-01-20 08:59:15

标签: javascript json ecmascript-6 azure-cosmosdb

我有一个DocumentDb数据库,其中一个文档类型具有以下结构:

{
    "structure": {
        "id": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3",
        "unittype": 1,
        "name": "MyCompany",
        "language": "nb-NO",
        "managers": [],
        "logoURL": null,
        "orginfo": {
            "Orgnumber": null,
            "Country": null,
            "Sector": null,
            "Code": null
        },
        "tags": [],
        "respondents": [],
        "childUnits": [
            {
                "id": "3fb44416-8fa8-4b60-8c0c-03b333d176f7",
                "unittype": 3,
                "name": "Marketing",
                "language": "nb-NO",
                "managers": [],
                "logoURL": null,
                "orginfo": {
                    "Orgnumber": null,
                    "Country": null,
                    "Sector": null,
                    "Code": null
                },
                "tags": [],
                "respondents": [],
                "childUnits": [
                    {
                        "id": "49932d6f-518e-4511-9bc9-f6f747a81968",
                        "unittype": 3,
                        "name": "Internet",
                        "language": "nb-NO",
                        "managers": [],
                        "logoURL": null,
                        "orginfo": {
                            "Orgnumber": null,
                            "Country": null,
                            "Sector": null,
                            "Code": null
                        },
                        "tags": [],
                        "respondents": [],
                        "childUnits": [],
                        "Parent": "3fb44416-8fa8-4b60-8c0c-03b333d176f7"
                    },
                    {
                        "id": "aa76010d-ae59-49b1-b929-9572eb536cc6",
                        "unittype": 3,
                        "name": "DM",
                        "language": "nb-NO",
                        "managers": [],
                        "logoURL": null,
                        "orginfo": {
                            "Orgnumber": null,
                            "Country": null,
                            "Sector": null,
                            "Code": null
                        },
                        "tags": [],
                        "respondents": [],
                        "childUnits": [],
                        "Parent": "3fb44416-8fa8-4b60-8c0c-03b333d176f7"
                    }
                ],
                "Parent": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3"
            },
            {
                "id": "be1d142a-e09d-4828-aceb-07d65321da5d",
                "unittype": 3,
                "name": "Support",
                "language": "nb-NO",
                "managers": [],
                "logoURL": null,
                "orginfo": {
                    "Orgnumber": null,
                    "Country": null,
                    "Sector": null,
                    "Code": null
                },
                "tags": [],
                "respondents": [],
                "childUnits": [],
                "Parent": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3"
            }
        ],
        "Parent": null
    },
    "id": "07b4c7c5-7324-4eef-9e4e-9deb70615ec4",
    "type": "organization",
    "owner": "auth0|571f2eb34247998a66726b02",
    "public": false,
    "_rid": "GPFbALqREAMNAAAAAAAAAA==",
    "_self": "dbs/GPFbAA==/colls/GPFbALqREAM=/docs/GPFbALqREAMNAAAAAAAAAA==/",
    "_etag": "\"00004707-0000-0000-0000-5881cef40000\"",
    "_attachments": "attachments/",
    "_ts": 1484902132
}

这是旧系统的重建,其中所有内容都存储在关系数据库中,并且每个UnitchildUnits属性中的对象)最初都是表中的一行。在我们最大的客户之一进行测试时,我们最终得到的结构超过500个。超过3000名受访者。 (我没有在此演示中添加任何内容,但Respondent对象包含电子邮件(必填)和可能的单元格编号。)

结果并不好。在我的(相当强壮的)devpc上本地运行,结构的检索大约需要2-3秒。 DocumentDb不支持文档部分的检索。因此,每当用户点击树视图中的单元时,整个结构就会重新发送(这部分我可能会缓存,但如果用户更改了某些内容,我将需要存储整个内容,然后将其读回)

然而,

DocumentDb 支持支持的是Javascript存储过程,它使用Chakra,就我所见,它符合ES2015标准。

所以我的想法是创建一个存储过程,我将id提供给文档(组织)和id以供单元检索。它搜索json文档并检索我想要的单位并将其发回。

这是否可以不使用外部库,只有ES2015功能?

3 个答案:

答案 0 :(得分:1)

性能的最佳方法是利用文档内JOIN - https://www.documentdb.com/sql/demo#JOIN

假设结构属性实际上是文档的一部分,JOIN查询看起来像这样:

SELECT c.id, childUnit 
FROM c JOIN childUnit IN c.structure.childUnits 
WHERE c.structure.id = "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" 
    AND childUnit.id = "3fb44416-8fa8-4b60-8c0c-03b333d176f7"*

如果结构属性实际上不是原始文档的一部分,则JOIN查询将如下所示:

SELECT c.id, childUnit 
FROM c JOIN childUnit IN c.childUnits 
WHERE c.id = "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" 
    AND childUnit.id = "3fb44416-8fa8-4b60-8c0c-03b333d176f7"*

此类查询将仅返回文档中指定的子单元。 WHERE过滤器中的单元ID childUnit id 可提高查询效果。

答案 1 :(得分:0)

Array.prototype.find解决了大部分问题。

如果需要,您可以填充函数:MDN official polyfill

var db = {
    "structure": {
        "id": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3",
        "unittype": 1,
        "name": "MyCompany",
        "language": "nb-NO",
        "managers": [],
        "logoURL": null,
        "orginfo": {
            "Orgnumber": null,
            "Country": null,
            "Sector": null,
            "Code": null
        },
        "tags": [],
        "respondents": [],
        "childUnits": [
            {
                "id": "3fb44416-8fa8-4b60-8c0c-03b333d176f7",
                "unittype": 3,
                "name": "Marketing",
                "language": "nb-NO",
                "managers": [],
                "logoURL": null,
                "orginfo": {
                    "Orgnumber": null,
                    "Country": null,
                    "Sector": null,
                    "Code": null
                },
                "tags": [],
                "respondents": [],
                "childUnits": [
                    {
                        "id": "49932d6f-518e-4511-9bc9-f6f747a81968",
                        "unittype": 3,
                        "name": "Internet",
                        "language": "nb-NO",
                        "managers": [],
                        "logoURL": null,
                        "orginfo": {
                            "Orgnumber": null,
                            "Country": null,
                            "Sector": null,
                            "Code": null
                        },
                        "tags": [],
                        "respondents": [],
                        "childUnits": [],
                        "Parent": "3fb44416-8fa8-4b60-8c0c-03b333d176f7"
                    },
                    {
                        "id": "aa76010d-ae59-49b1-b929-9572eb536cc6",
                        "unittype": 3,
                        "name": "DM",
                        "language": "nb-NO",
                        "managers": [],
                        "logoURL": null,
                        "orginfo": {
                            "Orgnumber": null,
                            "Country": null,
                            "Sector": null,
                            "Code": null
                        },
                        "tags": [],
                        "respondents": [],
                        "childUnits": [],
                        "Parent": "3fb44416-8fa8-4b60-8c0c-03b333d176f7"
                    }
                ],
                "Parent": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3"
            },
            {
                "id": "be1d142a-e09d-4828-aceb-07d65321da5d",
                "unittype": 3,
                "name": "Support",
                "language": "nb-NO",
                "managers": [],
                "logoURL": null,
                "orginfo": {
                    "Orgnumber": null,
                    "Country": null,
                    "Sector": null,
                    "Code": null
                },
                "tags": [],
                "respondents": [],
                "childUnits": [],
                "Parent": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3"
            }
        ],
        "Parent": null
    },
    "id": "07b4c7c5-7324-4eef-9e4e-9deb70615ec4",
    "type": "organization",
    "owner": "auth0|571f2eb34247998a66726b02",
    "public": false,
    "_rid": "GPFbALqREAMNAAAAAAAAAA==",
    "_self": "dbs/GPFbAA==/colls/GPFbALqREAM=/docs/GPFbALqREAMNAAAAAAAAAA==/",
    "_etag": "\"00004707-0000-0000-0000-5881cef40000\"",
    "_attachments": "attachments/",
    "_ts": 1484902132
};
function getDocument(orgID, docID) {
    //Variable to hold traversal progress
    var extract = db
        .structure
        .childUnits
        .find(function findFunc(organization) {
        return organization.id == orgID;
    });
    //Return false if we found no organization
    if (typeof extract == "undefined") {
        return false;
    }
    //Traverse organization children
    extract = extract
        .childUnits
        .find(function findFunc(document) {
        return document.id == docID;
    });
    //Return false if we found no organization
    if (typeof extract == "undefined") {
        return false;
    }
    //if we reach this point we found a result, which we can then return
    return extract;
}
//Running test
console.log(getDocument("3fb44416-8fa8-4b60-8c0c-03b333d176f7", "aa76010d-ae59-49b1-b929-9572eb536cc6"));
console.log(getDocument("3fb44416-8fa8-4b60-8c0c-03b333d176f7", "ERR"));
console.log(getDocument("ERR", "aa76010d-ae59-49b1-b929-9572eb536cc6"));
console.log(getDocument("ERR", "ERR"));

答案 2 :(得分:0)

您可以使用Array#some迭代和递归样式。



function getObject(object, id) {
    var r;
    return function iter(o) {
        if (o.id === id) {
            r = o;
            return true;
        }
        if (Array.isArray(o.childUnits)) {
            return o.childUnits.some(iter);
        }
    }(object) && r || undefined;
}

var data = { structure: { id: "7d2d5d3f-0c82-4910-aa0b-54d8067588a3", unittype: 1, name: "MyCompany", language: "nb-NO", managers: [], logoURL: null, orginfo: { Orgnumber: null, Country: null, Sector: null, Code: null }, tags: [], respondents: [], childUnits: [{ id: "3fb44416-8fa8-4b60-8c0c-03b333d176f7", unittype: 3, name: "Marketing", language: "nb-NO", managers: [], logoURL: null, orginfo: { Orgnumber: null, Country: null, Sector: null, Code: null }, tags: [], respondents: [], childUnits: [{ id: "49932d6f-518e-4511-9bc9-f6f747a81968", unittype: 3, name: "Internet", language: "nb-NO", managers: [], logoURL: null, orginfo: { Orgnumber: null, Country: null, Sector: null, Code: null }, tags: [], respondents: [], childUnits: [], Parent: "3fb44416-8fa8-4b60-8c0c-03b333d176f7" }, { id: "aa76010d-ae59-49b1-b929-9572eb536cc6", unittype: 3, name: "DM", language: "nb-NO", managers: [], logoURL: null, orginfo: { Orgnumber: null, Country: null, Sector: null, Code: null }, tags: [], respondents: [], childUnits: [], Parent: "3fb44416-8fa8-4b60-8c0c-03b333d176f7" }], Parent: "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" }, { id: "be1d142a-e09d-4828-aceb-07d65321da5d", unittype: 3, name: "Support", language: "nb-NO", managers: [], logoURL: null, orginfo: { Orgnumber: null, Country: null, Sector: null, Code: null }, tags: [], respondents: [], childUnits: [], Parent: "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" }], Parent: null }, id: "07b4c7c5-7324-4eef-9e4e-9deb70615ec4", type: "organization", owner: "auth0|571f2eb34247998a66726b02", public: false, _rid: "GPFbALqREAMNAAAAAAAAAA==", _self: "dbs/GPFbAA==/colls/GPFbALqREAM=/docs/GPFbALqREAMNAAAAAAAAAA==/", _etag: "\"00004707-0000-0000-0000-5881cef40000\"", _attachments: "attachments/", _ts: 1484902132 };

console.log(getObject(data.structure, 'foo'));
console.log(getObject(data.structure, 'aa76010d-ae59-49b1-b929-9572eb536cc6'));

.as-console-wrapper { max-height: 100% !important; top: 0; }