JSONPath 通配符步骤 (**) 在 MariaDB 中的工作原理

发布于

在MariaDB中使用JSON时,您可以使用JSONPath表达式来操作JSON文档中的数据。

MariaDB 提供的一项强大功能是通配符步骤 ()。这允许您以递归方式选择当前元素的所有子元素。**

通配符步骤是一个非标准扩展,在 MySQL  中也支持它的含义相同。

示例

下面是一个演示示例:

SET @json = '[
    { "name" : "Wag", "type" : "Dog" },
    { "name" : "Bark", "type" : "Dog" },
    { "name" : "Meow", "type" : "Cat" },
    { "name" : "Scratch", "type" : "Cat" }
]';

SELECT JSON_EXTRACT(@json, '$**.name');

结果:

+————————————+ | JSON_EXTRACT(@json, ‘$**.name’) | +————————————+ | [“Wag”, “Bark”, “Meow”, “Scratch”] | +————————————+

通配符步骤遍历所有对象并从其成员中选择值。name

在这个示例中,我们可以使用另一个选择器获得相同的结果。数组通配符选择器将帮助我们获得相同的结果:

SET @json = '[
    { "name" : "Wag", "type" : "Dog" },
    { "name" : "Bark", "type" : "Dog" },
    { "name" : "Meow", "type" : "Cat" },
    { "name" : "Scratch", "type" : "Cat" }
]';

SELECT JSON_EXTRACT(@json, '$[*].name');

结果:

+————————————+ | JSON_EXTRACT(@json, ‘$[*].name’) | +————————————+ | [“Wag”, “Bark”, “Meow”, “Scratch”] | +————————————+

相同的结果。

但是,如果我们使用不同的文档,情况就会发生变化。

例 2

在下面的示例中,我们在通配符步骤和数组选择器之间得到不同的结果:

SET @json = '[
    { 
        "name" : "Homer", 
        "pets" : [
            { 
            "name" : "Wag",
            "type" : "Dog"
            },
            { 
            "name" : "Scratch",
            "type" : "Cat"
            }
        ]    
    }
]';

SELECT 
    JSON_EXTRACT(@json, '$**.name'),
    JSON_EXTRACT(@json, '$[*].name');

结果:

+———————————+———————————-+ | JSON_EXTRACT(@json, ‘$**.name’) | JSON_EXTRACT(@json, ‘$[*].name’) | +———————————+———————————-+ | [“Homer”, “Wag”, “Scratch”] | [“Homer”] | +———————————+———————————-+

不同的结果。

结果显然取决于文档和 JSONPath 表达式的实际构造,而使用的选项器将取决于您的要求。

要记住的一件事是,通配符步骤不能是 JSONPath 表达式中的最后一步。它必须后跟数组或对象成员选择器步骤。

例 3

下面是一个示例,它从调用的所有数组(包括嵌套在其他文档中的数组)返回第二个数组元素:sizes

SET @json = '[
    { 
        "_id": 1, 
        "product": { 
            "name" : "Tuxedo", 
            "color" : "Blue",
            "sizes": [ "S", "M", "L" ],
            "accessories" : {
                "belt" : {
                    "color" : "Navy",
                    "sizes" : [ "Wide", "Narrow" ]
                },
                "tie" : {
                    "color" : "Black",
                    "sizes" : [ "Short", "Medium", "Long" ]
                }
            }
        }
    }
]';

SELECT JSON_EXTRACT(@json, '$**.sizes[1]');

结果:

+————————————-+ | JSON_EXTRACT(@json, ‘$**.sizes[1]’) | +————————————-+ | [“M”, “Narrow”, “Medium”] | +————————————-+

数组从零开始,因此引用所有数组中的第二个元素。$**.sizes[1]``sizes