【问题标题】:Duplicates returned in query on child object子对象查询中返回的重复项
【发布时间】:2015-03-09 16:43:14
【问题描述】:

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

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

【问题讨论】:

    标签: azure azure-cosmosdb


    【解决方案1】:

    我看到您正在尝试查询accountIdcontributorsaccountId 是否等于某个值。

    今天 - 您需要使用 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。那是因为这些数组元素中的每一个都与指定的查询匹配。

    【讨论】:

    • 感谢您的回复,但是这仍然会导致响应中出现重复的实体 - 应该只返回 2 个项目,一个用于 Bruce Banner,一个用于 Tony Stark。在这种情况下,type 无关紧要,我只希望检索提供的帐户 ID 是所有者或贡献者的不同记录。我将更新我的问题以包含所需的回复。
    • 啊,搞砸了...不幸的是,对于这个例子 - 查询中的重复是不可避免的(原因在我上面的回答中解释了)。您将需要编写一些应用程序逻辑来过滤结果:(
    猜你喜欢
    • 2021-09-14
    • 2013-03-04
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多