在cosmos db中转换JSON结构

时间:2018-05-22 06:07:27

标签: azure-cosmosdb

我有以下数据结构,我正在寻求转换。结构如下:

{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
    {
        "serviceTypeName": "OCCUPATIONAL THERAPY",
        "serviceTypeCode": "H",
        "providers": [
            {
                "providerNumber": "157833AC",
                "providerName": "DR TEST"
            }
        ],
        "serviceItems": [
            {
                "itemName": "INITIAL CONS",
                "itemNumber": "100",
                "fee": 0,
                "isReferenceItem": "true",
                "customisations": [
                    {
                        "practiceDisplayName": "First Assessment",
                        "fee": 50,
                        "isPracticeReferenceItem": "true"
                    }
                ]
            },
            {
                "itemName": "CONS TREAT",
                "itemNumber": "200",
                "fee": 0,
                "isReferenceItem": "true",
                "customisations": [
                    {
                        "practiceDisplayName": "Consult One",
                        "fee": 23.35,
                        "isPracticeReferenceItem": "true"
                    },
                    {
                        "practiceDisplayName": "Consult Two",
                        "fee": 15,
                        "isPracticeReferenceItem": "false"
                    }
                ]
            }
        ]
    }
]

}

我想要一个返回id,practiceId和extrasCoverservices(serviceTypeName,serviceTypeCode和serviceItems)的查询。我不想包含提供商信息。

我试过这个,但我需要在数组中指定元素的位置,我不想这样做。任何帮助将不胜感激。

SELECT  a.id
    , a.practiceId
    , [{"serviceTypeName": a.extrasCoverServices[0].serviceTypeName, "serviceTypeCode": a.extrasCoverServices[0].serviceTypeCode, "serviceItems": a.extrasCoverServices[0].serviceItems}]

更新

function sample(documentId) {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
    collection.getSelfLink(),
    'SELECT  ARRAY_CONCAT([{"itemId": s.itemId, "itemName": s.itemName,"itemNumber":s.itemNumber,"fee":s.fee,"isReferenceItem":s.isReferenceItem}], IS_DEFINED(s.customisations) ? s.customisations : [])  as extrasCoverServices FROM a JOIN e in a.extrasCoverServices JOIN s in e.serviceItems WHERE a.id =' + "'" + documentId + "'",
    function (err, feed, options) {
        if (err) throw err;
        if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
        else {
            console.log(feed.length);
            var result = feed.flatten(function(x) {
               return x.extrasCoverServices;   
            });
            getContext().getResponse().setBody(result);
        }
    });

if (!isAccepted) throw new Error('The query was not accepted by the server.');

}

3 个答案:

答案 0 :(得分:0)

请使用sql:

SELECT a.id,a.practiceId,e.serviceTypeName,e.serviceTypeCode,e.serviceItems
FROM a 
join e in a.extrasCoverServices a

结果:

enter image description here

如果您想将e.serviceTypeName,e.serviceTypeCode,e.serviceItems放入数组中,而不是与idpraticeId并行,我建议您在cosmos db中使用存储过程。

function sample() {
    var collection = getContext().getCollection();
    var isAccepted = collection.queryDocuments(
        collection.getSelfLink(),
        'SELECT c.id,c.practiceId,c.extrasCoverServices FROM root c',
        function (err, feed, options) {
            if (err) throw err;
            if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
            else {
                var returnResult = [];
                for(var i = 0;i<feed.length;i++){

                    var obj1 = {
                        id:"",
                        practiceId:"",
                        serviceArray :[]
                        };
                    obj1.id = feed[i].id;
                    obj1.practiceId = feed[i].practiceId;
                    var loopArray = feed[i].extrasCoverServices;
                    var serviceResult = [];
                    for(var j = 0;j<loopArray.length;j++){
                        var obj2 = {
                            serviceTypeName:"",
                            serviceTypeCode:"",
                            serviceItems:[] };
                        obj2.serviceTypeName=loopArray[j].serviceTypeName;
                        obj2.serviceTypeCode=loopArray[j].serviceTypeCode;
                        obj2.serviceItems=loopArray[j].serviceItems;
                        serviceResult.push(obj2);
                    }
                    obj1.serviceArray= serviceResult;
                    returnResult.push(obj1);
                }
                getContext().getResponse().setBody(returnResult);
            }
        });

    if (!isAccepted) throw new Error('The query was not accepted by the server.');
}

结果:

enter image description here

希望它对你有所帮助。

更新答案1:

为了您的评论中的进一步要求,我为您测试了一个SQL。

SELECT 
    a.id, 
    a.practiceId,
    [{
        "serviceTypeName": e.serviceTypeName, 
        "serviceTypeCode" : e.serviceTypeCode, 
        "serviceItems": [
            {"itemName": s.itemName,
            "itemNumber":s.itemNumber,
            "fee":s.fee,
            "isReferenceItem":s.isReferenceItem
            },
            {"practiceDisplayName":c.practiceDisplayName,
             "itemNumber":s.itemNumber,
             "fee": c.fee,
            "isPracticeReferenceItem":c.isPracticeReferenceItem 
            }
        ]
    }] as extrasCoverServices
FROM a 
join e in a.extrasCoverServices
join s in e.serviceItems
join c in s.customisations

但是,由于join

,结果有多个项目
[
    {
        "id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
        "practiceId": 2,
        "extrasCoverServices": [
            {
                "serviceTypeName": "OCCUPATIONAL THERAPY",
                "serviceTypeCode": "H",
                "serviceItems": [
                    {
                        "itemName": "INITIAL CONS",
                        "itemNumber": "100",
                        "fee": 0,
                        "isReferenceItem": "true"
                    },
                    {
                        "practiceDisplayName": "First Assessment",
                        "itemNumber": "100",
                        "fee": 50,
                        "isPracticeReferenceItem": "true"
                    }
                ]
            }
        ]
    },
    {
        "id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
        "practiceId": 2,
        "extrasCoverServices": [
            {
                "serviceTypeName": "OCCUPATIONAL THERAPY",
                "serviceTypeCode": "H",
                "serviceItems": [
                    {
                        "itemName": "CONS TREAT",
                        "itemNumber": "200",
                        "fee": 0,
                        "isReferenceItem": "true"
                    },
                    {
                        "practiceDisplayName": "Consult One",
                        "itemNumber": "200",
                        "fee": 23.35,
                        "isPracticeReferenceItem": "true"
                    }
                ]
            }
        ]
    },
    {
        "id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
        "practiceId": 2,
        "extrasCoverServices": [
            {
                "serviceTypeName": "OCCUPATIONAL THERAPY",
                "serviceTypeCode": "H",
                "serviceItems": [
                    {
                        "itemName": "CONS TREAT",
                        "itemNumber": "200",
                        "fee": 0,
                        "isReferenceItem": "true"
                    },
                    {
                        "practiceDisplayName": "Consult Two",
                        "itemNumber": "200",
                        "fee": 15,
                        "isPracticeReferenceItem": "false"
                    }
                ]
            }
        ]
    }
]

因此,我建议您在存储过程中处理结果以符合您的要求。

function sample() {
    var collection = getContext().getCollection();
    var isAccepted = collection.queryDocuments(
        collection.getSelfLink(),
        'SELECT a.id, a.practiceId,'+
    '[{'+
        '"serviceTypeName": e.serviceTypeName, '+
        '"serviceTypeCode" : e.serviceTypeCode, '+
        '"serviceItems": ['+
            '{"itemName": s.itemName,'+
            '"itemNumber":s.itemNumber,'+
            '"fee":s.fee,'+
            '"isReferenceItem":s.isReferenceItem'+
            '},'+
            '{"practiceDisplayName":c.practiceDisplayName,'+
             '"itemNumber":s.itemNumber,'+
             '"fee": c.fee,'+
            '"isPracticeReferenceItem":c.isPracticeReferenceItem '+
            '}'+
        ']'+
    '}] as extrasCoverServices'+
' FROM a '+
' join e in a.extrasCoverServices'+
' join s in e.serviceItems'+
' join c in s.customisations',
        function (err, feed, options) {
            if (err) throw err;
            if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
            else {
                var returnResult = [];
                var obj1 = {
                        id:"",
                        practiceId:"",
                        extrasCoverServices :[]
                        };
                var temp = "";
                for(var i = 0;i<feed.length;i++){
                    if(temp==feed[i].id){
                      var extrasArray = obj1.extrasCoverServices[0].serviceItems;
                      var serviceArray = feed[i].extrasCoverServices[0].serviceItems;
                      for(var j = 0;j<serviceArray.length;j++){
                          extrasArray.push(serviceArray[j]);
                      }
                      obj1.extrasCoverServices[0].serviceItems = extrasArray;
                    } else{
                        obj1.id = feed[i].id;
                        obj1.practiceId = feed[i].practiceId;
                        obj1.extrasCoverServices = feed[i].extrasCoverServices;
                        temp = feed[i].id;
                    }                
                }
                returnResult.push(obj1);
                getContext().getResponse().setBody(returnResult);
            }
        });

    if (!isAccepted) throw new Error('The query was not accepted by the server.');
}

处理结果:

[
    {
        "id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
        "practiceId": 2,
        "extrasCoverServices": [
            {
                "serviceTypeName": "OCCUPATIONAL THERAPY",
                "serviceTypeCode": "H",
                "serviceItems": [
                    {
                        "itemName": "INITIAL CONS",
                        "itemNumber": "100",
                        "fee": 0,
                        "isReferenceItem": "true"
                    },
                    {
                        "practiceDisplayName": "First Assessment",
                        "itemNumber": "100",
                        "fee": 50,
                        "isPracticeReferenceItem": "true"
                    },
                    {
                        "itemName": "CONS TREAT",
                        "itemNumber": "200",
                        "fee": 0,
                        "isReferenceItem": "true"
                    },
                    {
                        "practiceDisplayName": "Consult One",
                        "itemNumber": "200",
                        "fee": 23.35,
                        "isPracticeReferenceItem": "true"
                    },
                    {
                        "itemName": "CONS TREAT",
                        "itemNumber": "200",
                        "fee": 0,
                        "isReferenceItem": "true"
                    },
                    {
                        "practiceDisplayName": "Consult Two",
                        "itemNumber": "200",
                        "fee": 15,
                        "isPracticeReferenceItem": "false"
                    }
                ]
            }
        ]
    }
]

更新答案2:

好吧,我仍然专注于通过存储过程实现您的需求。 我将一个没有customisations数组的项目添加到serviceItems中,如下所示:

[
    {
        "id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
        "practiceId": 2,
        "extrasCoverServices": [
            {
                "serviceTypeName": "OCCUPATIONAL THERAPY",
                "serviceTypeCode": "H",
                "serviceItems": [
                    {
                        "itemName": "INITIAL CONS",
                        "itemNumber": "100",
                        "fee": 0,
                        "isReferenceItem": "true",
                        "customisations": [
                            {
                                "practiceDisplayName": "First Assessment",
                                "fee": 50,
                                "isPracticeReferenceItem": "true"
                            }
                        ]
                    },
                    {
                        "itemName": "CONS TREAT",
                        "itemNumber": "200",
                        "fee": 0,
                        "isReferenceItem": "true",
                        "customisations": [
                            {
                                "practiceDisplayName": "Consult One",
                                "fee": 23.35,
                                "isPracticeReferenceItem": "true"
                            },
                            {
                                "practiceDisplayName": "Consult Two",
                                "fee": 15,
                                "isPracticeReferenceItem": "false"
                            }
                        ]
                    },
                    {
                        "itemName": "FOR TEST",
                        "itemNumber": "333",
                        "fee": 20,
                        "isReferenceItem": "true"
                    }
                ]
            }
        ]
    }
]

SP代码:

function sample() {
    var collection = getContext().getCollection();
    var isAccepted = collection.queryDocuments(
        collection.getSelfLink(),
        'SELECT a.id, a.practiceId,'+
    '[{'+
        '"serviceTypeName": e.serviceTypeName, '+
        '"serviceTypeCode" : e.serviceTypeCode, '+
        '"serviceItems": e.serviceItems'+
    '}] as extrasCoverServices'+
' FROM a '+
' join e in a.extrasCoverServices',
        function (err, feed, options) {
            if (err) throw err;
            if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
            else {
                for(var i = 0;i<feed.length;i++){
                    var extraArray = feed[i].extrasCoverServices;
                    for(var j = 0;j<extraArray.length;j++){
                        var serviceArray = extraArray[j].serviceItems;
                        var array = [];
                        for(var k = 0;k<serviceArray.length;k++){
                            var o1 = {
                            "itemName": "",
                            "itemNumber":"",
                            "fee" : "",
                            "isReferenceItem":""
                            };
                            console.log(k+"----");
                            o1.itemName = serviceArray[k].itemName;
                            o1.itemNumber = serviceArray[k].itemNumber;
                            o1.fee = serviceArray[k].fee;
                            o1.isReferenceItem = serviceArray[k].isReferenceItem;
                            console.log(o1.itemName);
                            array.push(o1);
                            if(null != serviceArray[k].customisations){ 
                                var customisationsArray = serviceArray[k].customisations;
                                for(var p = 0;p<customisationsArray.length;p++){
                                     var o2 = {
                                        "practiceDisplayName": "",
                                        "itemNumber":"",
                                        "fee" : "",
                                        "isPracticeReferenceItem":""
                                    };
                                    o2.practiceDisplayName = customisationsArray[p].practiceDisplayName;
                                    o2.itemNumber = o1.itemNumber;
                                    o2.fee = customisationsArray[p].fee;
                                    o2.isPracticeReferenceItem = customisationsArray[p].isPracticeReferenceItem;
                                    array.push(o2);
                                }
                            }
                        }
                        feed[i].extrasCoverServices[j].serviceItems = array;
                    }   
                }               
                getContext().getResponse().setBody(feed);
            }
        });

    if (!isAccepted) throw new Error('The query was not accepted by the server.');
}

为了总结,我整理了你最后的SP代码。这是一个很好的主题。

function sample(documentId, itemId) {
var collection = getContext().getCollection();
var query = 'SELECT e.serviceTypeCode, '+
                    ' e.serviceTypeName, '+ 
                    ' s.itemNumber, '+
                    ' ARRAY_CONCAT( '+
                    ' [{ '+
                        ' "itemId": s.itemId, '+
                        ' "itemName": s.itemName, '+
                        ' "fee":s.fee, '+
                        ' "isReferenceItem":s.isReferenceItem '+
                    ' }], '+
                    ' IS_DEFINED(s.customisations) ? s.customisations : []) as extrasCoverServices '+ 
            ' FROM a '+ 
            ' JOIN e in a.extrasCoverServices '+ 
            ' JOIN s in e.serviceItems '+ 
            ' WHERE a.id = ' + "'" + documentId + "'";

var isAccepted = collection.queryDocuments(
    collection.getSelfLink(),
    query,
    function (err, feed, options) {

        if (err) throw err;

        if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');

        var returnResult = [];

        for(var i = 0; i<feed.length; i++) {
            let serviceItem = feed[i];
            let serviceItemsArray = feed[i].extrasCoverServices;

            for(var j = 0; j < serviceItemsArray.length; j++) {
                let item = serviceItemsArray[j];
                let mapped = {
                    serviceTypeCode: serviceItem.serviceTypeCode
                    , serviceTypeName: serviceItem.serviceTypeName
                    , itemId: item.itemId
                    , itemName: (item.itemName ? item.itemName : item.practiceDisplayName)
                    , itemNumber: serviceItem.itemNumber
                    , fee: item.fee
                    , isReferenceItem: ((item.isReferenceItem && item.isReferenceItem == true) ? item.isReferenceItem: false)
                    , isPracticeReferenceItem: (item.isPracticeReferenceItem && item.isPracticeReferenceItem == true ? item.isPracticeReferenceItem : false)
                };
                returnResult.push(mapped);
            }
        }

        if(itemId != undefined) {
            var filteredReturnResult = returnResult.filter(r => r.itemId == itemId);
            getContext().getResponse().setBody(filteredReturnResult);
            return
        }

        getContext().getResponse().setBody(returnResult);

if (!isAccepted) throw new Error('The query was not accepted by the server.');
})
}

答案 1 :(得分:0)

你几乎拥有它。为此,您可以使用以下功能:

  1. 使用join关键字
  2. 进行内部文档加入
  3. 使用{}包装器
  4. 的显式JSON组合

    第一个允许您访问要挑选的子项目,第二个允许您按照自己喜欢的方式将它们粘合在一起。

    您正在寻找的查询应该是这样的:

    SELECT 
        a.id, 
        a.practiceId,
        [{
            "serviceTypeName": e.serviceTypeName, 
            "serviceTypeCode" : e.serviceTypeCode, 
            "serviceItems": e.serviceItems
        }] as extrasCoverServices
    FROM a 
    join e in a.extrasCoverServices
    

    请注意,您可以在同一查询中将类似Sql的select与显式JSON构建相结合,以使查询更紧凑。另外,我建议您使用CosmosDB SQL query cheat sheet轻松发现工具箱中的内容。

答案 2 :(得分:0)

function sample(documentId, itemId) {
var collection = getContext().getCollection();
var query = 'SELECT e.serviceTypeCode, '+
                    ' e.serviceTypeName, '+ 
                    ' s.itemNumber, '+
                    ' ARRAY_CONCAT( '+
                    ' [{ '+
                        ' "itemId": s.itemId, '+
                        ' "itemName": s.itemName, '+
                        ' "fee":s.fee, '+
                        ' "isReferenceItem":s.isReferenceItem '+
                    ' }], '+
                    ' IS_DEFINED(s.customisations) ? s.customisations : []) as extrasCoverServices '+ 
            ' FROM a '+ 
            ' JOIN e in a.extrasCoverServices '+ 
            ' JOIN s in e.serviceItems '+ 
            ' WHERE a.id = ' + "'" + documentId + "'";

var isAccepted = collection.queryDocuments(
    collection.getSelfLink(),
    query,
    function (err, feed, options) {

        if (err) throw err;

        if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');

        var returnResult = [];

        for(var i = 0; i<feed.length; i++) {
            let serviceItem = feed[i];
            let serviceItemsArray = feed[i].extrasCoverServices;

            for(var j = 0; j < serviceItemsArray.length; j++) {
                let item = serviceItemsArray[j];
                let mapped = {
                    serviceTypeCode: serviceItem.serviceTypeCode
                    , serviceTypeName: serviceItem.serviceTypeName
                    , itemId: item.itemId
                    , itemName: (item.itemName ? item.itemName : item.practiceDisplayName)
                    , itemNumber: serviceItem.itemNumber
                    , fee: item.fee
                    , isReferenceItem: ((item.isReferenceItem && item.isReferenceItem == true) ? item.isReferenceItem: false)
                    , isPracticeReferenceItem: (item.isPracticeReferenceItem && item.isPracticeReferenceItem == true ? item.isPracticeReferenceItem : false)
                };
                returnResult.push(mapped);
            }
        }

        if(itemId != undefined) {
            var filteredReturnResult = returnResult.filter(r => r.itemId == itemId);
            getContext().getResponse().setBody(filteredReturnResult);
            return
        }

        getContext().getResponse().setBody(returnResult);

if (!isAccepted) throw new Error('The query was not accepted by the server.');
})

}