Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CosmosDB, help flatten and filter by nested array

I'm trying to flatten and filter my json data that is in a CosmosDB. The data looks like below and I would like to flatten everything in the array Variables and then filter by specific _id and Timestamp inside of the array:

{
"_id": 21032,
"FirstConnected": {
    "$date": 1522835868346
},
"LastUpdated": {
    "$date": 1523360279908
},
"Variables": [
    {
        "_id": 99999,
        "Values": [
            {
                "Timestamp": {
                    "$date": 1522835868347
                },
                "Value": 1
            }
        ]
    },
    {
        "_id": 99998,
        "Values": [
            {
                "Timestamp": {
                    "$date": 1523270312001
                },
                "Value": 8888
            }

       ]
    }
]
}   
like image 816
baatchen Avatar asked Apr 10 '18 16:04

baatchen


Video Answer


2 Answers

If you're only looking for filtering by the nested '_id' property then you could use ARRAY_CONTAINS w/ the partial_match argument set to true. The query would look something like this:

SELECT VALUE c
FROM c
WHERE ARRAY_CONTAINS(c.Variables, {_id: 99998}, true)

If you also want to flatten the array, then you could use JOIN

SELECT VALUE v
FROM v IN c.Variables
WHERE v._id = 99998
like image 129
Samer Boshra Avatar answered Oct 05 '22 11:10

Samer Boshra


If you want to flatten data from the Variables array with properties from the root object you can query your collection like this:

SELECT root._id, root.FirstConnected, root.LastUpdated, var.Values
FROM root 
JOIN var IN root.Variables
WHERE var._id = 99998

This will result into:

[
  {
    "_id": 21032,
    "FirstConnected": {
      "$date": 1522835868346
    },
    "LastUpdated": {
      "$date": 1523360279908
    },
    "Values": [
      {
        "Timestamp": {
          "$date": 1523270312001
        },
        "Value": 8888
      }
    ]
  }
]

If you want to even flatten the Values array you will need to write something like this:

SELECT root._id, root.FirstConnected, root.LastUpdated, 
       var.Values[0].Timestamp, var.Values[0]["Value"]
FROM root 
JOIN var IN root.Variables
WHERE var._id = 99998

Note that CosmosDB considers "Value" as a reserved keyword and you need to use an escpape syntax. The result for this query is:

[
  {
    "_id": 21032,
    "FirstConnected": {
      "$date": 1522835868346
    },
    "LastUpdated": {
      "$date": 1523360279908
    },
    "Timestamp": "1970-01-01T00:00:00Z",
    "Value": 8888
  }
]

Check for more details https://docs.microsoft.com/en-us/azure/cosmos-db/sql-api-sql-query#Advanced

like image 26
Sacha Bruttin Avatar answered Oct 05 '22 10:10

Sacha Bruttin