在子对象的查询中返回重复项

时间:2015-03-09 16:43:14

标签: azure azure-cosmosdb

我的文档中有这样的数据结构(请注意,为简洁起见,这是简化的):

{
    "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"
}]

1 个答案:

答案 0 :(得分:1)

我看到您正在尝试查询accountIdcontributors' s 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
}]

从结果中可以看出 - 正在为每个孩子返回一条记录:FooBarFizz。这是因为每个数组元素都匹配指定的查询。