CosmosDb запрашивает поле внутри объекта в массиве - PullRequest
1 голос
/ 05 мая 2020

Допустим, у меня есть этот документ:

{
  "body": {
    "items": [
      {
        "id": 1,
        "person": {
          "id": 100
        }
      },
      {
        "id": 2,
        "person": {
          "id": 101
        }
      }
    ]
  }
}

Я пытаюсь создать запрос, который будет выбирать документы на основе идентификатора человека в моем массиве элементов. Пока что я придумал это:

SELECT * FROM c WHERE ARRAY_CONTAINS(c.body.items, { 'id': 1 }, true)

Это работает для выбора на основе элемента самого объекта элемента, но если я попытаюсь сделать это:

SELECT * FROM c WHERE ARRAY_CONTAINS(c.body.items, { 'person.id': 100 }, true)

Это не работает.

Я пытаюсь построить свой запрос таким образом, чтобы я мог выполнить запрос, в котором он должен проверять документы, содержащие person.id = 100 и person.id = 101, но пока я просто хочу, чтобы работала основная часть.

Как мне исправить свой запрос, чтобы я мог искать внутренние объекты с помощью функции ARRAY_CONTAINS, или есть еще умный способ сделать это?

Изменить:

Я также пробовал:

SELECT * FROM c JOIN i IN c.body.items WHERE i.person.id = 100

Это работает, но мне нужно иметь возможность запрашивать на нескольких людях, поэтому что-то вроде

SELECT * FROM c JOIN i IN c.body.items WHERE i.person.id = 100 AND i.person.id

не сработает, поскольку ожидается, что элемент будет иметь person.id, равный 100 и 101, что невозможно.

1 Ответ

0 голосов
/ 05 мая 2020

Хм. Я тоже не мог заставить это работать, хотя, похоже, должно.

В качестве обходного пути вы можете выполнить самостоятельное присоединение, а затем выполнить фильтрацию на основе внутреннего идентификатора. Примечание: в моем примере я переименовал свойство id вашего внутреннего объекта человека в personid, так как этот запрос приводит к нескольким свойствам верхнего уровня id в противном случае:

select c.id, i.person.personid
from c
join i in c.body.items
where i.person.personid = 101

Результат:

[
    {
        "id": "1",
        "personid": 101
    }
]

Я мог бы избежать коллизии id верхнего уровня, оставив исходные свойства на месте с псевдонимом:

select c.id, i.person.id as personid
from c
join i in c.body.items
where i.person.id = 101

Вы также можете использовать синтаксис скобок для внутренних свойств , что эквивалентно и дает тот же результат:

select c.id, i.person['personid']
from c
join i in c.body.items
where i.person['personid'] = 101

Вышеупомянутый подход также работает при поиске нескольких идентификаторов людей. В качестве примера представьте себе другую запись (id=2), где массив содержит идентификаторы человека 102 и 103:

select c.id, i.person.personid
from c
join i in c.body.items
where array_contains([101,103],i.person.personid)

Это возвращает:

[
    {
        "id": "1",
        "personid": 101
    },
    {
        "id": "2",
        "personid": 103
    }
]

Альтернативный синтаксис:

select c.id, i.person.personid
from c
join i in c.body.items
where i.person.personid in (101,103)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...