#sql #azure #azure-cosmosdb
#sql #azure #azure-cosmosdb
Вопрос:
У меня есть коллекция с телом:
{
"id": "666",
"name": "Test",
"lastEvents": [
{
"show": false,
"eventType": "TYPE_1",
"creationDateTime": "2020-08-16T11:59:00"
},
{
"show": false,
"eventType": "TYPE_33",
"creationDateTime": "2020-10-14T06:11:00",
"control": "test repaired"
},
{
"show": false,
"eventType": "TYPE_33",
"creationDateTime": "2020-10-14T06:08:00",
"control": "test recovered"
}
],
"_rid": "kgsjAN-JFWEDQEQWESDAD==",
"_self": "JFWE=/docs/kgsjAN-JFWEDQEQWESDAD==/dbs/kgsjAA==/colls/kgsjAN",
"_etag": ""666-0000-750011b7-0000-5eec704f0000"",
"_attachments": "attachments/",
"_ts": 1592873510
}
И я хотел бы отфильтровать его по первому lastEvents.control
полю. Теперь я использую:
SELECT *
FROM root r
WHERE EXISTS(
SELECT VALUE n
FROM n IN r.lastEventFields
WHERE CONTAINS(n.control, "recovered", true)
)
но этот запрос выполняется через весь массив lastEvent. В моем случае я должен проверять только первый элемент с control
помощью поля.
Как я могу добиться желаемого поведения?
Ответ №1:
Если я не ошибаюсь, вы хотите получить документ, который является первым элементом, имеющим control
поле в lastEvents
массиве, и он должен содержать «восстановленную» строку.
Если это так, SQL не может выполнить ваше требование.
Обходной путь:
1. создайте UDF и lastEvents
массив циклов. UDF может стоить дорого, пожалуйста, обратите на это внимание. Если вам нужно, я могу предоставить JS-код.
2. добавьте файл в свой документ, чтобы проверить, соответствует ли он вашим потребностям на стороне клиента, прежде чем сохранять / обновлять документ. Если вы часто обновляете свой документ, это плохая альтернатива.
3. получите все ваши документы и отфильтруйте их на стороне клиента.
Комментарии:
1. Нет, потому что я не знаю точного индекса. Он не обязательно будет равен 0.
2. @ArtemDanilin Я обновил свой ответ. Я не уверен, что понимаю ваш смысл. Вы можете посмотреть.
3. Вы правы, @Steve Zhao, здесь нет недоразумений. Я знаю об UDF, и я уже пробовал это. В моем случае это будет стоить слишком дорого! Как вы думаете, есть ли способ решить мою проблему без UDF? Я хотел бы решить это с помощью «собственного SQL»
4. Я пытался использовать такие операторы, как TOP, OFFSET, но это не работает в подзапросах.
5. Я тоже пробовал. Подзапрос не поддерживает TOP, OFFSET. Я понятия не имею, как справиться с этим с помощью SQL.
Ответ №2:
Ваш запрос не возвращает мне никаких данных. Вот способ сделать это по-другому
SELECT c.id, c.name, s.show, s.eventType, s.control, s.creationDateTime
FROM c
join s IN c.lastEvents
WHERE IS_DEFINED(s.control) AND CONTAINS(s.control, "recovered", true)
Комментарии:
1. Да, я допустил ошибку в своем SQL. Но я хотел бы добиться другого результата. В настоящее время мой и ваш SQL находят весь массив lastEvent. Но в моем случае мне нужен только первый элемент массива, где поле ‘control’ является define
2. Если я вас правильно понимаю, вы хотите, чтобы ваш запрос остановил итерацию, как только он найдет то, что вы ищете. Я прав?
3. Я хочу получить документ, который является первым элементом, имеющим поле управления в массиве lastEvents, и он должен содержать «восстановленную» строку. Вы можете обратиться к разговору с @Steve Zhao