Сопоставление нескольких значений с помощью Azure Cosmos DB

#azure #azure-cosmosdb #azure-cosmosdb-sqlapi

Вопрос:

У меня есть следующий json в моей 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
    }
]
 

Теперь я пытаюсь применить фильтр на Technology.id и Рейтинг. Это означает, что я хочу выбрать все записи, например, с помощью C# с рейтингом = 1 и SQL с рейтингом = 2.

Что-то вроде

 (Technology.id = "d76d59a7-c9a3-404d-91dd-cf2596ee7501" and Rating = 1) OR (Technology.id = "5686189b-ccfc-41c6-bcdb-b56f80130b45" and Rating = 2)
 

Поскольку технология-это массив, который не работает.

Я тоже поиграл с ARRAY_CONTAINS ним, но у меня ничего не получилось.

 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)
 

Как я могу написать такой запрос?

Ответ №1:

Вы можете попробовать этот 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)
 

или

 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))
 

Ответ №2:

Вот запрос:

 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
 

Обратите внимание, что вы должны обязательно включить ключ раздела в этот запрос, чтобы избежать дополнительных задержек и затрат на запрос.

Если бы ключом раздела было поле «идентификатор», запрос выглядел бы следующим образом:

 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)
    
 

Запрос с ключом раздела имеет следующую статистику
введите описание изображения здесь