Skip to main content

關於 MongoDB

Q1: MongoDB 可以 Query 到幾層?

簡而言之,可以到很深入到無窮層的 Querying。

我們已以下資料為例

view_obj

{
"_id":"6192badb8b480205e9484a33",
"info":{
"name":"william",
"age":"30",
"friends":[
{
"name":"ken",
"age": 30
"home":{
"city":"Taipei",
"members":[
{
"name":"Grace",
"relationship":"mother"
},
{
"name":"PY",
"relationship":"father"
}
]
}
},
{
"name":"kevin",
"age": 35
"home":{
"city":"Tainan"
}
}
]
}
}

我們可以拆解到 nested 相當深層的欄位,以上述資料來說,以下範例提供基本的第二層欄位讀取

select
-- 第二層欄位
info.name,
info.age,
info.friends
from nested_07260

query two level

接下來到第三層欄位中,若有 array of object,常見的情境是希望可以攤平成 rows,後續不管是 join, where 等語法,或是任何 aggregation 等運算都可以延伸,這邊介紹 UNNEST 這個語法

(UNNEST: https://flow.cannerdata.com/docs/sql/sql_select/#unnest)

-- 拆解第三層欄位 (info -> friends[] -> name)
select
info.name,
friend.name,
friend.age,
friend.home
from nested_21691
cross join unnest(info.friends) as friend(name, age, home)

query three level

我們可以再深入到第五層欄位,以下範例我們搭配 CTE (with statement),使用 unnest 語法把第五層中 nested array 中的欄位拉到第一層做使用

-- 拆解第五層欄位 (info -> friends[] -> home -> members[] -> name)
with friends as (
select
info.name as info_name,
friend.name as friend_name,
friend.age as friend_age,
friend.home as friend_home
from nested_21691
cross join unnest(info.friends) as friend(name, age, home)
)
select
info_name,
friend_name,
friend_age,
friend_home.city,
friend_home_member.name as friend_home_member_name,
friend_home_member.relationship as friend_home_member_relationship
from friends
cross join unnest(friend_home.members) as friend_home_member(name, relationship)

query five level

理論上,一般情境使用下很難碰到 CannerFlow 在 CTS 上的系統限制,所以可以到相當深層欄位的存取,但在實務上,過於 nested 的欄位若需要大量的使用 CTS,仍會造成 performance 上些許的影響。


Q2: MongoDB 是巢狀,user 可否針對巢狀內容做 Search?可撈巢狀裡面的資料嗎?

CannerFlow 可處理複雜結構,像是 array, object,例如 https://docs.atlas.mongodb.com/sample-data/sample-analytics/#sample_analytics.transactions 這邊的 sample dataset 可以用下面這種方式 query

select
transactions[1].date
from transactions_96448
where any_match(transactions, t -> t.amount > 7000)

找出 transactions 這個 array-of-object field 中有任何 element 的 amount > 7000 的 row,並取出第一筆交易的 date

可以參考 Array document: https://flow.cannerdata.com/docs/sql/functions/array