【问题标题】:Access deeper elements of a JSON using postgresql 9.4使用 postgresql 9.4 访问 JSON 的更深层元素
【发布时间】:2015-07-14 20:42:04
【问题描述】:

我希望能够在 json 字段中访问存储在 json 中的更深层次的元素,存储在 postgresql 数据库中。例如,我希望能够从下面提供的 json 访问遍历路径 states->events->time 的元素。这是我正在使用的 postgreSQL 查询:

SELECT 
    data#>> '{userId}' as user, 
    data#>> '{region}' as region, 
    data#>>'{priorTimeSpentInApp}' as priotTimeSpentInApp, 
    data#>>'{userAttributes, "Total Friends"}' as totalFriends 
from game_json 
WHERE game_name LIKE 'myNewGame' 
LIMIT 1000

这是来自 json 字段的示例记录

{
    "region": "oh",
    "deviceModel": "inHouseDevice",
    "states": [
        {
            "events": [
                {
                    "time": 1430247045.176,
                    "name": "Session Start",
                    "value": 0,
                    "parameters": {
                        "Balance": "40"
                    },
                    "info": ""
                },
                {
                    "time": 1430247293.501,
                    "name": "Mission1",
                    "value": 1,
                    "parameters": {
                        "Result": "Win ",
                        "Replay": "no",
                        "Attempt Number": "1"
                    },
                    "info": ""
                }
            ]
        }
    ],
    "priorTimeSpentInApp": 28989.41467999999,
    "country": "CA",
    "city": "vancouver",
    "isDeveloper": true,
    "time": 1430247044.414,
    "duration": 411.53,
    "timezone": "America/Cleveland",
    "priorSessions": 47,
    "experiments": [],
    "systemVersion": "3.8.1",
    "appVersion": "14312",
    "userId": "ef617d7ad4c6982e2cb7f6902801eb8a",
    "isSession": true,
    "firstRun": 1429572011.15,
    "priorEvents": 69,
    "userAttributes": {
        "Total Friends": "0",
        "Device Type": "Tablet",
        "Social Connection": "None",
        "Item Slots Owned": "12",
        "Total Levels Played": "0",
        "Retention Cohort": "Day 0",
        "Player Progression": "0",
        "Characters Owned": "1"
    },
    "deviceId": "ef617d7ad4c6982e2cb7f6902801eb8a"
}

该 SQL 查询有效,只是它没有给我任何 totalFriends 的返回值(例如 data#>>'{userAttributes, "Total Friends"}' as totalFriends)。我认为问题的一部分是事件落在方括号内(我不知道在 json 格式中表示什么)而不是花括号,但我也无法从 userAttributes 键中提取值。

如果有人可以帮助我,我将不胜感激。

很抱歉,如果其他地方有人问过这个问题。我对 postgresql 甚至 json 都很陌生,以至于我无法想出正确的术语来找到这个(和相关)问题的答案。

【问题讨论】:

  • Your query works。这可能是您的实际数据存在问题。
  • 是的,好像是这样。一旦你说我能够找出问题所在。对于我试图抓住的每个元素,我都需要一个 group by 语句。然后它起作用了。

标签: json postgresql


【解决方案1】:

你一定要熟悉the basics of jsonjson functions and operators in Postgres

在第二个来源中注意运算符->->>。 一般规则:使用->获取json对象,->>获取json值作为文本。 使用这些运算符,您可以以返回正确值 'Total Friends' 的方式重写您的查询:

select
    data->>'userId' as user, 
    data->>'region' as region, 
    data->>'priorTimeSpentInApp' as priotTimeSpentInApp, 
    data->'userAttributes'->>'Total Friends' as totalFriends 
from game_json 
where game_name like 'myNewGame';

方括号中的 JSON 对象是 json 数组的元素。 Json 数组可能有很多元素。 元素通过索引访问。 Json 数组从 0 开始索引(数组的第一个元素的索引为 0)。 示例:

select
    data->'states'->0->'events'->1->>'name'
from game_json 
where game_name like 'myNewGame'; 
-- returns "Mission1"

【讨论】:

  • data->'userAttributes'->>'Total Friends'data#>>'{userAttributes, "Total Friends"}' 的意思完全一样。事实上,后者在json的情况下会更快,因为前者会被解析两次(我不确定jsonb)。
  • @pozs - 我更喜欢第一种形式,因为它在 jsonb 上要快一点。我在 json 上检查过,你是对的,第二个确实快得多。
【解决方案2】:
select
    data->'states'->0->'events'->1->>'name'
from game_json 
where game_name like 'myNewGame';

这确实帮助了我

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-06
    • 2015-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 2021-05-06
    相关资源
    最近更新 更多