【问题标题】:Athena - How to query by nested json value?Athena - 如何通过嵌套的 json 值查询?
【发布时间】:2021-11-11 18:04:32
【问题描述】:

在 Athena 中,我们试图获取所有含有种子的水果。我们面临的问题是种子 true/false 嵌套在 json 中,我们似乎无法在 WHERE 子句中对其进行过滤。我们只能在嵌套的 json 路径中将 SELECT 它作为 hasSeeds 时看到结果,但这会返回所有种子结果 truefalse 而不仅仅是 true

-- This returns all seeds, but we want to filter in the WHERE clause by hasSeeds true
SELECT foodId, foodType, json_extract(payload,'$.food.info.seeds') AS hasSeeds
FROM "food_table"
WHERE foodType = 'fruit'

-- 3 attempts to filter by nested json value seeds true (not working)
SELECT * FROM
(SELECT foodId, foodType, json_extract(payload,'$.food.info.seeds') AS hasSeeds
FROM "food_table"
WHERE foodType = 'fruit')
WHERE hasSeeds = true

SELECT foodId, foodType, json_extract(payload,'$.food.info.seeds') AS hasSeeds
FROM "food_table"
WHERE foodType = 'fruit' and hasSeeds = true

SELECT foodId, foodType, json_extract(payload,'$.food.info.seeds') AS hasSeeds
FROM "food_table"
WHERE foodType = 'fruit' and json_extract(payload,'$.food.info.seeds') = true

知道如何在嵌套 json 上按 hasSeeds true 过滤时让查询按预期工作吗?

使用 JSON 结构更新:

{
  "foodId": 1,
  "foodType": "fruit",
  "payload": {
    "food": {
      "name": "apple",
      "info": {
        "seeds": true,
        "calories": 95
      }
    }
  }
}

{
  "foodId": 2,
  "foodType": "fruit",
  "payload": {
    "food": {
      "name": "banana"
    }
  }
}

{
  "foodId": 3,
  "foodType": "vegetable",
  "payload": {
  }
}

{
  "foodId": 4,
  "foodType": "fruit",
  "payload": {
  }
}

尝试了这个查询,但返回的结果不正确:

WITH dataset(jsn) AS (
    values (JSON '{"payload":{"food":{"info":{"seeds":true}}}}')
)

SELECT foodId, foodType, json_extract(payload,'$.food.info.seeds') AS hasSeeds, jsn
FROM "food_table", dataset
WHERE cast(json_extract_scalar(jsn, '$.payload.food.info.seeds') AS BOOLEAN) = true

基本上,hasSeeds 返回为 true,这是正确的,但其他食品,例如那些缺少有效载荷的孩子的食品仍然使用 jsn 字段返回,而不是实际上仅通过类似的方式仅查询 WHERE 子句payload.food.info.seeds = true

知道怎么解决吗?

【问题讨论】:

  • 你能分享一下json例子吗?
  • 更新了 json 示例

标签: json amazon-dynamodb amazon-athena


【解决方案1】:

假设你有下一个json结构,你需要使用json_extract_scalar:

WITH dataset(jsn) AS (
    values (JSON '{"food":{"info":{"seeds":true}}}')
)

SELECT *
FROM dataset
WHERE cast(json_extract_scalar(jsn, '$.food.info.seeds') AS BOOLEAN) = true

UPD

基于提供的 json WHERE 子句应该类似于:

WHERE try(cast(json_extract_scalar(payload, '$.payload.food.info.seeds') AS BOOLEAN)) = true

【讨论】:

  • 感谢您的参与!我添加了一个更新,因为它没有按预期工作,我们需要调整什么吗?
  • @BigMike with dataset.... 是设置一些示例数据,你不应该加入,你应该在你的数据上使用json_extract_scalar。即WHERE cast(json_extract_scalar(payload, '$.payload.food.info.seeds') AS BOOLEAN) = true
  • @BigMike 因为并非每个有效负载都有您需要将json_extract_scalar 包装到try 中的数据
  • hmm.. 但是数据在“food_table”数据库表中,所以我们无法查询您的意思是?
  • @BigMike 你应该查询你的数据。 dataset 是我的带有 json 字段的示例数据,我用它来展示如何提取布尔值 seeds 值。
猜你喜欢
  • 1970-01-01
  • 2019-04-18
  • 2020-08-01
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 2014-08-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多