Pivotal Knowledge Base

关注

如何在OQL中处理非一致结构的JSON数据

适用于

GemFire 8 及之后版本

目的

本文的目的在于说明使OQL成功查询非一致性结构数据的方法。

描述

我们从一个包含嵌套数组的对象开始,其中包括我们需要查询的元素:

{ "name": "Jane Doe", "addresses": [..., { "city": "New York" }, ...] }

为了找到地址中有New York的人,可以使用如下的查询:

SELECT DISTINCT person FROM /people AS person, person.addresses AS address WHERE address.city = 'New York'

但是,如果我们在同一个region中含有如下的对象,该查询将报错:

{ "name": "John Doe" }

The error stems from the inclusion of person.addresses in the FROM clause because the FROM clause may only include paths that resolve to arrays.

该错误源自FROM从句中包含了person.addresses,而FROM从句中只能包括可以被分解为数据的路径

So how can a query be written given that person.addresses may not exist or may not be an array?

所以,考虑到person.addresses可能不存在或者不是一个数据的时候,如何来写这个query呢?

一个推荐的办法是使用is_defined从句来处理这种情况:

select distinct person from /jsonRegion person where is_defined( person.addresses) and 'New York' in (select a.city from person.addresses a)

这样我们可以认为初始对象已经被改为一个包括更深层嵌套的对象,其结构如下:

{ 
"name":"Jane Doe",
"addresses":[
{
"phoneNumbers":[
{
"number":"123-456-7891"
},
{
"number":"987-654-4321"
}
]
},
{
"city":"New York"
}
]
}

我们如何在所有人中查询拥有电话号码“123-456-7891”的人呢?

该查询同样需要考虑到地址不存在的情况:

select person.name from (select * from /jsonRegion jr where is_defined(jr.addresses)) person, (select * from person.addresses) a where is_defined(a.phoneNumbers) and '123-456-7891' in (select n.number from a.phoneNumbers n)

评论

由 Zendesk 提供技术支持