【问题标题】:WHERE clause on an array in Azure DocumentDbAzure DocumentDb 中数组的 WHERE 子句
【发布时间】:2020-10-22 20:10:50
【问题描述】:

在这样的 Azure Documentdb 文档中

{
"id": "WakefieldFamily",
"parents": [
    { "familyName": "Wakefield", "givenName": "Robin" },
    { "familyName": "Miller", "givenName": "Ben" }
],
"children": [
    {
        "familyName": "Merriam", 
        "givenName": "Jesse", 
        "gender": "female", 
        "grade": 1,
        "pets": [
            { "givenName": "Goofy" },
            { "givenName": "Shadow" }
        ]
    },
    { 
      "familyName": "Miller", 
      "givenName": "Lisa", 
      "gender": "female", 
      "grade": 8 
    }
],
  "address": { "state": "NY", "county": "Manhattan", "city": "NY" },
  "isRegistered": false
};

如何查询以获取宠物名字为“Goofy”的孩子?

看起来下面的语法无效

Select * from root r
WHERE r.children.pets.givenName="Goofy"

相反,我需要这样做

Select * from root r
WHERE r.children[0].pets[0].givenName="Goofy"

这并不是真正搜索数组。

关于我应该如何处理此类查询的任何建议?

【问题讨论】:

    标签: azure-cosmosdb nosql


    【解决方案1】:

    您应该利用 DocumentDB 的 JOIN 子句,它的作用与 RDBM 中的 JOIN 略有不同(因为 DocumentDB 处理无模式文档的非规范化数据模型)。​​

    简单地说,您可以将 DocumentDB 的 JOIN 视为自联接,可用于在嵌套的 JSON 对象之间形成交叉积。

    在查询宠物名字为“Goofy”的孩子的上下文中,您可以尝试:

    SELECT 
        f.id AS familyName,
        c AS child,
        p.givenName AS petName 
    FROM Families f 
    JOIN c IN f.children 
    JOIN p IN c.pets
    WHERE p.givenName = "Goofy"
    

    返回:

    [{
        familyName: WakefieldFamily,
        child: {
            familyName: Merriam,
            givenName: Jesse,
            gender: female,
            grade: 1,
            pets: [{
                givenName: Goofy
            }, {
                givenName: Shadow
            }]
        },
        petName: Goofy
    }]
    

    参考:http://azure.microsoft.com/en-us/documentation/articles/documentdb-sql-query/

    编辑:

    您还可以使用ARRAY_CONTAINS 函数,如下所示:

    SELECT food.id, food.description, food.tags
    FROM food
    WHERE food.id = "09052" or ARRAY_CONTAINS(food.tags.name, "blueberries")
    

    【讨论】:

    • 感谢您的回答。我了解到我只需要加入阵列,但不需要每个节点都关闭。再次感谢,拯救了我的一天。
    • 我将如何使用 Linq 做到这一点?
    • select f.* 由于某种原因无效?我必须手动指定根元素的所有属性?
    • 您可以简单地使用SELECT f获取根文档下的所有属性
    • 我在 azure docdb 查询资源管理器中使用示例记录条目并得到空结果但 [select * from c where array_contains(c.Parents.FirstName, "Ben")] 尝试此语句 [select *来自 c 其中 c.LastName = "Wakefield" ]。出乎意料的是,更复杂的联接语句 [ select f.LastName as familyName, p as parent from Familes f join p in f.Parents where p.FirstName = "Ben" ] 有效。关于我忽略了什么以使更简单的 array_contains 方法起作用的任何见解,或者我应该去哪里了解为什么使用上面给出的 q/a 细节我期望的东西不起作用?
    【解决方案2】:

    我认为 ARRAY_CONTAINS 函数自 2014 年得到回答以来发生了变化。我必须使用以下方法才能使其工作。

    SELECT * FROM c
    WHERE ARRAY_CONTAINS(c.Samples, {"TimeBasis":"5MIN_AV", "Value":"5.105"},true)
    

    Samples 是我的 JSON 数组,它包含具有许多属性的对象,包括上述两个。

    【讨论】:

    • 这有帮助。但即使这样对我也不起作用,因为它是写的。我必须将 TimeBasis 放在引号 (") 中,就像您为“Value”所做的那样。
    • @Krumelur 感谢您的提醒,我的回答只是一个错字。 :-)
    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多