Дубликаты возвращаются в запросе для дочернего объекта

У меня есть такая структура данных в моем документе (обратите внимание, что это упрощено для краткости):

{
    "id": "c1c1c1c1-c1c1-c1c1-c1c1-c1c1c1c1c1c1",
    "name": "Bruce Banner",
    "accountId": "a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1",
    "contributors": [{
        "accountId": "a2a2a2a2-a2a2-a2a2-a2a2-a2a2a2a2a2a2",
        "type": "Foo"
    },{
        "accountId": "a3a3a3a3-a3a3-a3a3-a3a3-a3a3a3a3a3a3",
        "type": "Bar"
    }]
},
{
    "id": "c2c2c2c2-c2c2-c2c2-c2c2-c2c2c2c2c2c2",
    "name": "Tony Stark",
    "accountId": "a2a2a2a2-a2a2-a2a2-a2a2-a2a2a2a2a2a2",
    "contributors": [{
        "accountId": "a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1",
        "type": "Fizz"
    }]
},

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

SELECT e.id, e.accountId, e.name
FROM Entitity e
JOIN co IN e.contributors
WHERE e.accountId = 'a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1'
OR co.accountId = 'a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1'

Результат:

[{
    "id": "c1c1c1c1-c1c1-c1c1-c1c1-c1c1c1c1c1c1",
    "accountId": "a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1",
    "name": "Bruce Banner"
},{
    "id": "c1c1c1c1-c1c1-c1c1-c1c1-c1c1c1c1c1c1",
    "accountId": "a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1",
    "name": "Bruce Banner"
},{
    "id": "c2c2c2c2-c2c2-c2c2-c2c2-c2c2c2c2c2c2",
    "accountId": "a2a2a2a2-a2a2-a2a2-a2a2-a2a2a2a2a2a2",
    "name": "Tony Stark"
}]

Как видите, первый объект (Bruce Banner) дублируется. Если я удалю пункт JOIN, он будет работать правильно. Может ли кто-нибудь сказать мне, почему это так, и как я могу избежать дублирования?

Изменить. Для ясности, это мой ожидаемый ответ:

[{
    "id": "c1c1c1c1-c1c1-c1c1-c1c1-c1c1c1c1c1c1",
    "accountId": "a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1",
    "name": "Bruce Banner"
},{
    "id": "c2c2c2c2-c2c2-c2c2-c2c2-c2c2c2c2c2c2",
    "accountId": "a2a2a2a2-a2a2-a2a2-a2a2-a2a2a2a2a2a2",
    "name": "Tony Stark"
}]

person Rory McCrossan    schedule 09.03.2015    source источник


Ответы (1)


Я вижу, вы пытаетесь узнать, равно ли accountId или contributors accountId какому-то значению.

Сегодня вам нужно использовать оператор JOIN для выполнения перекрестного произведения, чтобы запрашивать все элементы в массиве JSON (примечание: вам не нужен JOIN для запроса по определенному индексу массива, например, WHERE e.contributors[0].accountId = 'a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1').

В вашем примере abpve вы получите дубликаты запроса, что неизбежно. Вы захотите реализовать некоторую логику приложения для фильтрации дубликатов из результата запроса.

Чтобы лучше понять поведение JOIN (подумайте о простом перекрестном произведении), попробуйте добавить поле из массива, с которым вы создаете перекрестное произведение (например, co.type):

SELECT e.id, e.accountId, e.name, co.type
FROM Entitity e
JOIN co IN e.contributors
WHERE e.accountId = 'a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1'
OR co.accountId = 'a1a1a1a1-a1a1-a1a1-a1a1-a1a1a1a1a1a1'

что приводит к:

[{
    id: c1c1c1c1 - c1c1 - c1c1 - c1c1 - c1c1c1c1c1c1,
    accountId: a1a1a1a1 - a1a1 - a1a1 - a1a1 - a1a1a1a1a1a1,
    name: Bruce Banner,
    type: Foo
}, {
    id: c1c1c1c1 - c1c1 - c1c1 - c1c1 - c1c1c1c1c1c1,
    accountId: a1a1a1a1 - a1a1 - a1a1 - a1a1 - a1a1a1a1a1a1,
    name: Bruce Banner,
    type: Bar
}, {
    id: c2c2c2c2 - c2c2 - c2c2 - c2c2 - c2c2c2c2c2c2,
    accountId: a2a2a2a2 - a2a2 - a2a2 - a2a2 - a2a2a2a2a2a2,
    name: Tony Stark,
    type: Fizz
}]

Как видно из результатов, для каждого из дочерних элементов возвращается запись: Foo, Bar и Fizz. Это потому, что каждый из этих элементов массива соответствует указанному запросу.

person Andrew Liu    schedule 10.03.2015
comment
Спасибо за ответ, однако это по-прежнему приводит к дублированию объекта в ответе - должно быть возвращено только 2 элемента, один для Bruce Banner и один для Tony Stark. type в этом случае не имеет значения, я хочу получить только отдельные записи, где предоставленный идентификатор учетной записи является либо владельцем, либо участником. Я обновлю свой вопрос, чтобы включить желаемый ответ. - person Rory McCrossan; 11.03.2015
comment
Ага... К сожалению для этого примера - дубликаты запроса неизбежны (по причинам, объясненным в моем ответе выше). Вам нужно будет написать некоторую логику приложения для фильтрации результатов :( - person Andrew Liu; 12.03.2015