Cosmos Db (need any sort of iteration mechanism) - azure

want to check my document have same value in object A for eg:
{
"id": "1234-wrew-1234314"
"_ts": 1672840679
"A": [
{
"Id": "123",
"values": 167273168512
},
{
"Id": "1234",
"values": 1672731685
},
{
"Id": "123456",
"values": 1673461685
}
]
}
have this document now i want to check all values have same value or not is there any way to do this?
what i already tried :
select EXISTS(
SELECT VALUE n
FROM n IN c.A
WHERE c.A[0].values= c.A[1].values) as a
from c
where c.id ="1234-wrew-1234314"
its working fine if i have only 2 records in object A but i want generic solution to handle any number of records in object.
i also try with array_contain but its not working.
Thanks in advance.

Does this do what you need?
SELECT d.MaxValue = d.MinValue ? 'All the same' : 'Not the same'
FROM
(
SELECT MAX(a.values) AS MaxValue ,
MIN(a.values) AS MinValue
FROM c
JOIN a IN c.A
WHERE c.id = "1234-wrew-1234314"
) d

Related

CosmosDb query to return arrays

I have the following data in my Collection
{
"id": "00000000-0000-0000-454c-4b74472b01d8",
"GroupId": 1,
"Location": "London",
"Status": "Ok"
},
{
"id": "d129adeb-d1bf-4a89-afe3-93e3f60589fb",
"GroupId": 1,
"Location": "Liverpool",
"Status": "Ok"
},
{
"id": "85ecf875-0e32-40b5-823a-a2545694f9b6",
"GroupId": 2,
"Location": "Manchester",
"Status": "Nok"
}
I need to build a query to get all possible value by Group for filtering.
Let's say for "GroupId": 1 I need result like
{
"Location": [
"London",
"Liverpool"
],
"Status": [
"Ok"
]
}
for "GroupId": 2 the response:
{
"Location": [
"Manchester",
],
"Status": [
"Nok"
]
}
Could you please help my to build such query? I don't know even if it possible with CosmosDb.
I have tried so far something like this but it doesn't work
select
(
select VALUE c.Location
FROM c
WHERE c.GroupId = 1
GROUP BY c.Location
) as Location,
(
select VALUE c.Status
FROM c
WHERE c.GroupId = 1
GROUP BY c.Status
) as Status
from c
WHERE c.GroupId = 1
and this
select
[
(SELECT VALUE [c.Location] from c)
] as Location,
[
(SELECT VALUE [c.Status] from c)
] as Status
from c
where c.GroupId = 1
Please help or suggest how to solve that. Thank you in advance.
It's not possible to do this with the way your data is modeled.
With the ARRAY expression you can do this in a subquery for arrays within your document. But not when the data spans documents as it is the case here.

select non unique record based on a unique combination of 2 fields cosmos db

I have many records in Cosmos DB container with the following structure (sample):
{
"id": "aaaa",
"itemCode": "1234",
"itemDesc": "TEST",
"otherfileds": ""
}
{
"id": "bbbb",
"itemCode": "1234",
"itemDesc": "TEST2",
"otherfileds": ""
}
{
"id": "cccc",
"itemCode": "5678",
"itemDesc": "HELLO",
"otherfileds": ""
}
{
"id": "dddd",
"itemCode": "5678",
"itemDesc": "HELLO",
"otherfileds": ""
}
{
"id": "eeee",
"itemCode": "9012",
"itemDesc": "WORLD",
"otherfileds": ""
}
{
"id": "ffff",
"itemCode": "9012",
"itemDesc": "WORLD",
"otherfileds": ""
}
Now I want to select records from this where an item code have a non distinct item description. Based on the above example records, I would like to return item code 1234 since it has different values of item descriptions in other records.
{
"id": "aaaa",
"itemCode": "1234",
"itemDesc": "TEST",
"otherfileds": ""
}
{
"id": "bbbb",
"itemCode": "1234",
"itemDesc": "TEST2",
"otherfileds": ""
}
I have tried the below query, but realised, it will return the duplicate entries which has same item code and description only.
select count(1) from (select distinct value d.itemCode FROM (SELECT
c.itemCode, c.itemDesc, COUNT(1) as dupcount
FROM
c where c.itemCode<>null
GROUP BY
c.itemCode, c.itemDesc) d where d.dupcount>1 )
But I need to find records where the same item code is having different item descriptions (the query above will return only records which has more than one occurrence of item code/descriptions, ie, item code 9012 and 5678)
EDIT
I think i managed to form the query to filter these results by 2 sub queries (I think this could be improved though).
select e.itemCode from (select d.itemCode, count(1) as dupcount FROM
(SELECT
c.itemCode, c.itemDesc
FROM
c where c.itemCode<>null
GROUP BY
c.itemCode, c.itemDesc) d group by d.itemCode )e where e.dupcount>1
I think I managed to form the query to filter these results by 2 sub-queries (I think this could be improved though).
select distinct e.itemCode from (select d.itemCode, count(1) as dupcount FROM
(SELECT
c.itemCode, c.itemDesc
FROM
c where c.itemCode<>null
GROUP BY
c.itemCode, c.itemDesc) d group by d.itemCode )e where e.dupcount>1

How to SQL query a nested list and array in a MS Azure CosmosDB?

I have the following (Azure) CosmosDB (sub) structure, that has 2 nested arrays:
{
"id": "documentTypes",
"SomeThing": "SomeThing",
"configuration": [
{
"language": "en",
"list": [
{
"id": 1,
"name": "Supporting Documents"
},
{
"id": 2,
"name": "Summary PDF"
},
]
}
],
}
I have tried the following queries, with poor results.
SELECT * FROM c WHERE c.documentTypes.configuration[0].list[0].id FROM c
and
SELECT
p.id,
p.name
FROM f
JOIN c IN f.configuration
JOIN p IN c.list
WHERE c.id == 'documentTypes'
Q: How can I get only the list of name and ids?
You need this?
SELECT ARRAY(SELECT VALUE e FROM c JOIN d IN c["configuration"] JOIN e IN d["list"]) AS Result FROM c
Output:
[
{
"Result": [
{
"id": 1,
"name": "Supporting Documents"
},
{
"id": 2,
"name": "Summary PDF"
}
]
} ]
My own solution was similar to Sajeetharan's:
SELECT list.id, list.name FROM c
JOIN configuration IN c.configuration
JOIN list IN configuration.list
WHERE c.id = 'documentTypes'
This to me look a bit simpler by not needing [""] and the ARRAY() function, and also doesn't produce the additional Result item. I have not idea if there is any performance difference.

Cosmos SQL where sessions[any].venues[any].id = this

Using this structure as an example, saved in a Cosmos database (course-database) in a collection (course-collection):
{
"courseId": "courseId",
"sessions": [
{
"sessionId": "sessionId1",
"venues": [
{
"id": "venueId1"
},
{
"id": "venueId2"
}
]
},
{
"sessionId": "sessionId2",
"venues": [
{
"id": "venueId3"
},
{
"id": "venueId4"
}
]
}
]
}
How do you create the SQL:
Count the total number of courses, where a course has at least one session, which has at least one venue, which has an ID equals to e.g. venueId3
I've got this so far, but it restricts to the first item of the list, as opposed to just any:
SELECT COUNT(c.id) FROM c WHERE c.sessions[0].venues[0].id = "id"
The answer was join:
SELECT COUNT(c.id)
FROM c
JOIN s in c.sessions
JOIN v in s.venues
WHERE CONTAINS(v.id,"venueId3")
You would then add a new join the deeper in the JSON you would want to go e.g. if venues had an array of contacts:
SELECT COUNT(c.id)
FROM c
JOIN s in c.sessions
JOIN v in s.venues
JOIN co in v.contacts
WHERE CONTAINS(co.id,"contactId")

Matching multiple values using Azure Cosmos DB

I have following json in my Cosmos DB:
[
{
"FirstName": "FirstName",
"LastName": "LastName",
"TechnologyRatings": [
{
"Technology": {
"Name": "C#",
"id": "d76d59a7-c9a3-404d-91dd-cf2596ee7501"
},
"Rating": 1
},
{
"Technology": {
"Name": "SQL",
"id": "5686189b-ccfc-41c6-bcdb-b56f80130b45",
},
"Rating": 2
}
],
"id": "7c34718f-ef01-4b40-9a03-f0880f424fd4",
"ModifiedAt": "2021-05-28T09:55:37.6260562Z",
"_rid": "GyRkALN-kZcCAAAAAAAAAA==",
"_self": "dbs/GyRkAA==/colls/GyRkALN-kZc=/docs/GyRkALN-kZcCAAAAAAAAAA==/",
"_etag": "\"00000000-0000-0000-53a7-9c3d693501d7\"",
"_attachments": "attachments/",
"_ts": 1622195737
}
]
Now I try to apply a filter on Technology.id and Rating. Meaning I want to select all entries for example with C# with Rating = 1 and SQL with Rating = 2.
Something like
(Technology.id = "d76d59a7-c9a3-404d-91dd-cf2596ee7501" and Rating = 1) OR (Technology.id = "5686189b-ccfc-41c6-bcdb-b56f80130b45" and Rating = 2)
As TechnologyRatings is an array that doesn't work.
I also played around with ARRAY_CONTAINS but I didn't get it to work.
SELECT VALUE c FROM c JOIN t IN c.TechnologyRatings WHERE ARRAY_CONTAINS([{"id": "d76d59a7-c9a3-404d-91dd-cf2596ee7501", "Rating": 1}, {"id": "5686189b-ccfc-41c6-bcdb-b56f80130b45", "Rating": 2}], {"id": t.Technology.id, "Rating": t.Rating}, true)
How can I write such a query?
You can try this SQL:
SELECT
Distinct VALUE c
FROM c
JOIN t IN c.TechnologyRatings
WHERE (t.Technology.id = "d76d59a7-c9a3-404d-91dd-cf2596ee7501" and t.Rating = 1) OR (t.Technology.id = "5686189b-ccfc-41c6-bcdb-b56f80130b45" and t.Rating = 2)
or
SELECT
VALUE c
FROM c
WHERE
(ARRAY_CONTAINS(c.TechnologyRatings,{"Technology": {"id":"d76d59a7-c9a3-404d-91dd-cf2596ee7501"}},true) and ARRAY_CONTAINS(c.TechnologyRatings,{"Rating":1},true))
OR
(ARRAY_CONTAINS(c.TechnologyRatings,{"Technology": {"id":"5686189b-ccfc-41c6-bcdb-b56f80130b45"}},true) and ARRAY_CONTAINS(c.TechnologyRatings,{"Rating":2},true))
Here's the query:
SELECT VALUE root FROM root JOIN (SELECT VALUE EXISTS(SELECT VALUE tRatings FROM root JOIN tRatings IN root["TechnologyRatings"]
WHERE ((tRatings["Technology"]["id"] = "5686189b-ccfc-41c6-bcdb-b56f80130b45") OR (tRatings["Technology"]["id"] = "d76d59a7-c9a3-404d-91dd-cf2596ee7501")))) AS found WHERE found
Note that you must make sure to include a partition key on that query to avoid extra delays and costs on the query.
If the partition key was the 'id' field, the query would look like this:
SELECT VALUE root FROM root JOIN (SELECT VALUE EXISTS(SELECT VALUE tRatings FROM root JOIN tRatings IN root["TechnologyRatings"]
WHERE ((tRatings["Technology"]["id"] = "5686189b-ccfc-41c6-bcdb-b56f80130b45") OR (tRatings["Technology"]["id"] = "d76d59a7-c9a3-404d-91dd-cf2596ee7501")))) AS found
WHERE ((root["id"] = "5686189b-ccfc-41c6-bcdb-b56f80130b45") AND found)
The query with the partition key has the following stats

Resources