Store and query extremely large amount of JSON data - sql

Context:
300000 lines of JSON data are generated approximately every five seconds by a game's remote public API. This data disappears immediately after the next update and is never accessible again. I want to be able to save compressed historical records of this data, which can be reliably and efficiently indexed and searched.
Question:
What is the best database system to store JSON data on this scale, considering possible compression methods and most importantly query efficiency?
EDIT Adding example unpacked JSON (one object out of around 30000):
{
"accountName": "Kabancheg11",
"lastCharacterName": "KabanNeedBuff",
"id": "427d66d977b5a63af08b3c39173a1a567eb783fde6d6f97df505dbe6c1fa5988",
"stash": "~b/o 30 chaos",
"stashType": "PremiumStash",
"items": [
{
"verified": false,
"w": 1,
"h": 1,
"ilvl": 71,
"icon": "http://web.poecdn.com/image/Art/2DItems/Amulets/Amulet37.png?scale=1&w=1&h=1&v=25bebeac11abfd9f7931d574765521093",
"league": "Hardcore",
"id": "a7bb36a28e55865b9d766dcebd5bc0c6893d5ecb6cd9870dc0bcd3c9f1164f29",
"sockets": [],
"name": "",
"typeLine": "Onyx Amulet",
"identified": false,
"corrupted": false,
"lockedToCharacter": false,
"implicitMods": [
"+15 to all Attributes"
],
"frameType": 3,
"x": 11,
"y": 0,
"inventoryId": "Stash1",
"socketedItems": []
},
{
"verified": false,
"w": 1,
"h": 3,
"ilvl": 75,
"icon": "http://web.poecdn.com/image/Art/2DItems/Weapons/OneHandWeapons/Daggers/Heartbreaker.png?scale=1&w=1&h=3&v=b4f18d5c0602a17381df6a45b4c57be33",
"league": "Hardcore",
"id": "c955f054ffae9439e5d257c4a444b02423b2dbe304d1fa581227d21a0f203aa9",
"sockets": [
{
"group": 0,
"attr": "D"
},
{
"group": 0,
"attr": "D"
}
],
"name": "<<set:MS>><<set:M>><<set:S>>Heartbreaker",
"typeLine": "Royal Skean",
"identified": true,
"corrupted": false,
"lockedToCharacter": false,
"properties": [
{
"name": "Dagger",
"values": [],
"displayMode": 0
},
{
"name": "Physical Damage",
"values": [
[
"15-59",
0
]
],
"displayMode": 0
},
{
"name": "Critical Strike Chance",
"values": [
[
"6.60%",
0
]
],
"displayMode": 0
},
{
"name": "Attacks per Second",
"values": [
[
"1.45",
0
]
],
"displayMode": 0
}
],
"requirements": [
{
"name": "Level",
"values": [
[
"50",
0
]
],
"displayMode": 0
},
{
"name": "Dex",
"values": [
[
"71",
0
]
],
"displayMode": 1
},
{
"name": "Int",
"values": [
[
"102",
0
]
],
"displayMode": 1
}
],
"implicitMods": [
"40% increased Global Critical Strike Chance"
],
"explicitMods": [
"45% increased Spell Damage",
"+50 to maximum Mana",
"+50 to maximum Energy Shield",
"10% faster start of Energy Shield Recharge",
"Your Spells have Culling Strike"
],
"flavourText": [
"A heart can be stabbed by thoughts, \r",
"If your mind is sharp enough."
],
"frameType": 3,
"x": 0,
"y": 9,
"inventoryId": "Stash2",
"socketedItems": []
},
{
"verified": false,
"w": 2,
"h": 3,
"ilvl": 75,
"icon": "http://web.poecdn.com/image/Art/2DItems/Weapons/OneHandWeapons/Scepters/MontregulsGrasp.png?scale=1&w=2&h=3&v=fed985831c32e8e25b7663608a2b7a5c3",
"league": "Hardcore",
"id": "a78e6bfff62145c78b92714cc7de10e4484c42745d48b585ef905b3972c2a319",
"sockets": [
{
"group": 0,
"attr": "S"
},
{
"group": 0,
"attr": "S"
}
],
"name": "",
"typeLine": "Void Sceptre",
"identified": false,
"corrupted": false,
"lockedToCharacter": false,
"properties": [
{
"name": "One Handed Mace",
"values": [],
"displayMode": 0
},
{
"name": "Physical Damage",
"values": [
[
"42-63",
0
]
],
"displayMode": 0
},
{
"name": "Critical Strike Chance",
"values": [
[
"6.50%",
0
]
],
"displayMode": 0
},
{
"name": "Attacks per Second",
"values": [
[
"1.25",
0
]
],
"displayMode": 0
}
],
"requirements": [
{
"name": "Str",
"values": [
[
"104",
0
]
],
"displayMode": 1
},
{
"name": "Int",
"values": [
[
"122",
0
]
],
"displayMode": 1
}
],
"implicitMods": [
"15% increased Elemental Damage"
],
"frameType": 3,
"x": 0,
"y": 6,
"inventoryId": "Stash3",
"socketedItems": []
},
{
"verified": false,
"w": 2,
"h": 4,
"ilvl": 74,
"icon": "http://web.poecdn.com/image/Art/2DItems/Weapons/TwoHandWeapons/TwoHandAxes/TwoHandAxe11Unique.png?scale=1&w=2&h=4&v=49f4f7aff220d356fc6300d7454df63a3",
"league": "Hardcore",
"id": "c8d722c909939d1fda4431722c732e7af4c17781d9d9c58da613bf776ea1e993",
"sockets": [
{
"group": 0,
"attr": "D"
}
],
"name": "",
"typeLine": "Superior Karui Chopper",
"identified": false,
"corrupted": false,
"lockedToCharacter": false,
"properties": [
{
"name": "Two Handed Axe",
"values": [],
"displayMode": 0
},
{
"name": "Quality",
"values": [
[
"+10%",
1
]
],
"displayMode": 0
},
{
"name": "Physical Damage",
"values": [
[
"88-138",
1
]
],
"displayMode": 0
},
{
"name": "Critical Strike Chance",
"values": [
[
"5.00%",
0
]
],
"displayMode": 0
},
{
"name": "Attacks per Second",
"values": [
[
"1.15",
0
]
],
"displayMode": 0
}
],
"requirements": [
{
"name": "Str",
"values": [
[
"151",
0
]
],
"displayMode": 1
},
{
"name": "Dex",
"values": [
[
"43",
0
]
],
"displayMode": 1
}
],
"frameType": 3,
"x": 2,
"y": 0,
"inventoryId": "Stash4",
"socketedItems": []
},
{
"verified": false,
"w": 2,
"h": 3,
"ilvl": 51,
"icon": "http://web.poecdn.com/image/Art/2DItems/Armours/BodyArmours/StrInt3AUnique2.png?scale=1&w=2&h=3&v=3ef1aa6bc50b635ca334653ca95485a63",
"league": "Hardcore",
"id": "26c55af00fb31f63bec7229b622c3c79fb6efcfa03d3d2595672a92778d04d99",
"sockets": [
{
"group": 0,
"attr": "I"
},
{
"group": 1,
"attr": "I"
}
],
"name": "<<set:MS>><<set:M>><<set:S>>Ambu's Charge",
"typeLine": "Crusader Chainmail",
"identified": true,
"corrupted": false,
"lockedToCharacter": false,
"properties": [
{
"name": "Armour",
"values": [
[
"477",
1
]
],
"displayMode": 0
},
{
"name": "Energy Shield",
"values": [
[
"141",
1
]
],
"displayMode": 0
}
],
"requirements": [
{
"name": "Level",
"values": [
[
"43",
0
]
],
"displayMode": 0
},
{
"name": "Str",
"values": [
[
"64",
0
]
],
"displayMode": 1
},
{
"name": "Int",
"values": [
[
"64",
0
]
],
"displayMode": 1
}
],
"explicitMods": [
"182% increased Armour and Energy Shield",
"+15% to all Elemental Resistances",
"Gain an Endurance Charge when you take a Critical Strike",
"2% of Life Regenerated per second while on Low Life",
"Share Endurance Charges with nearby party members"
],
"flavourText": [
"Nothing stops the pain like a courageous rush into battle."
],
"frameType": 3,
"x": 0,
"y": 0,
"inventoryId": "Stash5",
"socketedItems": []
},
{
"verified": false,
"w": 1,
"h": 1,
"ilvl": 64,
"icon": "http://web.poecdn.com/image/Art/2DItems/Jewels/basicint.png?scale=1&w=1&h=1&v=cd579ea22c05f1c6ad2fd015d7a710bd3",
"league": "Hardcore",
"id": "34103c553f0ae3e36c695664a7540dd6e547338596c33554ca3a8443dd5349c1",
"sockets": [],
"name": "<<set:MS>><<set:M>><<set:S>>Cataclysm Heart",
"typeLine": "Cobalt Jewel",
"identified": true,
"corrupted": false,
"lockedToCharacter": false,
"explicitMods": [
"2% increased Cast Speed",
"7% increased maximum Energy Shield",
"+13% to Lightning Resistance"
],
"descrText": "Place into an allocated Jewel Socket on the Passive Skill Tree. Right click to remove from the Socket.",
"frameType": 2,
"x": 0,
"y": 3,
"inventoryId": "Stash6",
"socketedItems": []
},
{
"verified": false,
"w": 1,
"h": 1,
"ilvl": 0,
"icon": "http://web.poecdn.com/image/Art/2DItems/Gems/VaalGems/VaalArc.png?scale=1&w=1&h=1&v=b4f32328e279496ebb227521e8dce6793",
"support": false,
"league": "Hardcore",
"id": "be9a23cfe0a53942b19c22da32b7d461b464838749110d04689e15498dcad86b",
"sockets": [],
"name": "",
"typeLine": "Vaal Arc",
"identified": true,
"corrupted": true,
"lockedToCharacter": false,
"properties": [
{
"name": "Vaal, Spell, Chaining, Lightning",
"values": [],
"displayMode": 0
},
{
"name": "Level",
"values": [
[
"20 (Max)",
0
]
],
"displayMode": 0
},
{
"name": "Mana Cost",
"values": [
[
"0",
0
]
],
"displayMode": 0
},
{
"name": "Souls Per Use",
"values": [
[
"32",
0
]
],
"displayMode": 0
},
{
"name": "Can Store %0 Use",
"values": [
[
"1",
0
]
],
"displayMode": 3
},
{
"name": "Cast Time",
"values": [
[
"0.80 sec",
0
]
],
"displayMode": 0
},
{
"name": "Critical Strike Chance",
"values": [
[
"5.00%",
0
]
],
"displayMode": 0
},
{
"name": "Damage Effectiveness",
"values": [
[
"80%",
0
]
],
"displayMode": 0
}
],
"requirements": [
{
"name": "Level",
"values": [
[
"70",
0
]
],
"displayMode": 0
},
{
"name": "Int",
"values": [
[
"155",
0
]
],
"displayMode": 1
}
],
"secDescrText": "An arc of lightning stretches from the caster to a targeted nearby enemy and chains on to many additional targets.",
"explicitMods": [
"Deals 49 to 938 Lightning Damage",
"Chain +40 Times",
"100% chance to Shock enemies"
],
"descrText": "Place into an item socket of the right colour to gain this skill. Right click to remove from a socket.",
"frameType": 4,
"x": 0,
"y": 4,
"inventoryId": "Stash7",
"socketedItems": []
}
],
"public": true
}
An example query could be asking how many of the items nested inside every object like the one shown above have an ilvl field greater than or equal to an integer.

Related

Vega Zoomable USA Map

I want to use this map https://vega.github.io/vega/examples/zoomable-world-map/ but only for USA.
I used this spec.
private specVega = {
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "An interactive world map supporting pan and zoom.",
"width": 900,
"height": 500,
"autosize": "none",
"signals": [
{ "name": "tx", "update": "width / 2" },
{ "name": "ty", "update": "height / 2" },
{
"name": "scale",
"value": 150,
"on": [{
"events": {"type": "wheel", "consume": true},
"update": "clamp(scale * pow(1.0005, -event.deltaY * pow(16, event.deltaMode)), 150, 3000)"
}]
},
{
"name": "angles",
"value": [0, 0],
"on": [{
"events": "mousedown",
"update": "[rotateX, centerY]"
}]
},
{
"name": "cloned",
"value": null,
"on": [{
"events": "mousedown",
"update": "copy('projection')"
}]
},
{
"name": "start",
"value": null,
"on": [{
"events": "mousedown",
"update": "invert(cloned, xy())"
}]
},
{
"name": "drag", "value": null,
"on": [{
"events": "[mousedown, window:mouseup] > window:mousemove",
"update": "invert(cloned, xy())"
}]
},
{
"name": "delta", "value": null,
"on": [{
"events": {"signal": "drag"},
"update": "[drag[0] - start[0], start[1] - drag[1]]"
}]
},
{
"name": "rotateX", "value": 0,
"on": [{
"events": {"signal": "delta"},
"update": "angles[0] + delta[0]"
}]
},
{
"name": "centerY", "value": 0,
"on": [{
"events": {"signal": "delta"},
"update": "clamp(angles[1] + delta[1], -60, 60)"
}]
}
],
"projections": [
{
"name": "projection",
"type": "mercator",
"scale": {"signal": "scale"},
"rotate": [{"signal": "rotateX"}, 0, 0],
"center": [0, {"signal": "centerY"}],
"translate": [{"signal": "tx"}, {"signal": "ty"}]
}
],
"data": [
{
"name": "counties",
values: null,
"format": {"type": "topojson", "feature": "states"},
},
{
"name": "graticule",
"transform": [
{ "type": "graticule", "step": [15, 15] }
]
}
],
"marks": [
{
"type": "shape",
"from": {"data": "graticule"},
"encode": {
"enter": {
"strokeWidth": {"value": 1},
"stroke": {"value": "#ddd"},
"fill": {"value": null}
}
},
"transform": [
{ "type": "geoshape", "projection": "projection" }
]
},
{
"type": "shape",
"from": {"data": "states"},
"encode": {
"enter": {
"strokeWidth": {"value": 0.5},
"stroke": {"value": "#bbb"},
"fill": {"value": "#e5e8d3"}
}
},
"transform": [
{ "type": "geoshape", "projection": "projection" }
]
}
]
}
this.specVega["data"][0]["values"] = "data/us-10m.json" (this is just for understanding which data i used)
So i put data for only US here, but it didn't work. Got an error in console:
Undefined data set name: "states"
In general i just need a zoomable map for USA only, which i am going to use as a bubble map.
If this map has a zoom i would definitely use it https://vega.github.io/vega-lite/examples/geo_layer.html
Here is an working example of USA map by states or counties in "albersUsa" projection. Zooming is by mouse wheel and panning by mouse click-drag. For better performance, zooming and panning are best done with states instead of counties.
View in Vega online editor
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "An interactive USA map supporting pan and zoom.",
"width": 900,
"height": 500,
"autosize": "none",
"signals": [
{
"name": "signal_show_map_graticule",
"value": true,
"bind": {
"input": "checkbox",
"name": "Map graticule: "}
},
{
"name": "signal_states_or_counties",
"value": "states",
"bind": { "input": "select",
"options": ["states", "counties"],
"name": "Map areas: "
}
},
{
"name": "signal_map_scale",
"value": 1000,
"bind": {"input": "range", "min": 1000, "max": 4000, "step": 50, "name": "Map scale: "},
"on": [{
"events": {"type": "wheel", "consume": true},
"update": "round(clamp(signal_map_scale * pow(1.0005, -event.deltaY * pow(16, event.deltaMode)), 1000, 4000))"
}]
},
{ "name": "signal_translate_xy",
"value": [450, 250],
"update": "[clamp(signal_translate_last_xy[0] + signal_mouse_delta_xy[0], -300, 1200), clamp(signal_translate_last_xy[1] + signal_mouse_delta_xy[1], -200, 800)]"
},
{ "name": "signal_translate_last_xy",
"value": [450, 250],
"on": [{
"events": [
{"type": "mousedown"}
],
"update": "signal_translate_xy"
}]
},
{
"name": "signal_mouse_start_xy",
"value": [0, 0],
"on": [{
"events": [
{"type": "mousedown"}
],
"update": "xy()"
}]
},
{
"name": "signal_mouse_drag_xy",
"value": [0, 0],
"on": [{
"events": [
{
"type": "mousemove",
"between": [
{"type": "mousedown"},
{"type": "mouseup"}
]
}
],
"update": "xy()"
}]
},
{
"name": "signal_mouse_delta_xy",
"value": [0, 0],
"update": "[signal_mouse_drag_xy[0] - signal_mouse_start_xy[0], signal_mouse_drag_xy[1] - signal_mouse_start_xy[1]]"
}
],
"projections": [
{
"name": "map_projection",
"type": "albersUsa",
"scale": {"signal": "signal_map_scale"},
"translate": {"signal": "signal_translate_xy"}
}
],
"data": [
{
"name": "data_geo_usa",
"url": "data/us-10m.json",
"format": {
"type": "topojson",
"feature": {"signal": "signal_states_or_counties"}
}
},
{
"name": "data_geo_graticule",
"transform": [
{ "type": "graticule", "step": [5, 5] }
]
}
],
"marks": [
{
"type": "shape",
"from": {"data": "data_geo_graticule"},
"encode": {
"enter": {
"strokeWidth": {"value": 1},
"stroke": {"value": "#ddd"}
},
"update": {
"strokeOpacity": {"signal": "signal_show_map_graticule ? 1 : 0"}
}
},
"transform": [
{ "type": "geoshape", "projection": "map_projection" }
]
},
{
"type": "shape",
"from": {"data": "data_geo_usa"},
"encode": {
"enter": {
"strokeWidth": {"value": 0.5},
"stroke": {"value": "#bbb"},
"fill": {"value": "#e5e8d3"}
}
},
"transform": [
{ "type": "geoshape", "projection": "map_projection" }
]
}
]
}
Change "data" to:
"data": [
{
"name": "states",
"url": "data/us-10m.json",
"format": {"type": "topojson", "feature": "states"}
},
View in Vega online editor
Apologies but I'm not a mapping expert. I have the following where zoom works fine but the drag is a little janky but definitely useable. It would probably take me quite a while to get this any better.
Roy's answer is another option for you.
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"autosize": "none",
"background": "white",
"padding": 5,
"width": 500,
"height": 300,
"signals": [
{"name": "tx", "update": "width / 2"},
{"name": "ty", "update": "height / 2"},
{
"name": "scale",
"value": 685,
"on": [
{
"events": {"type": "wheel", "consume": true},
"update": "clamp(scale * pow(1.0005, -event.deltaY * pow(16, event.deltaMode)), 150, 3000)"
}
]
},
{
"name": "angles",
"value": [222, 146],
"on": [{"events": "mousedown", "update": "[rotateX, centerY]"}]
},
{
"name": "cloned",
"value": null,
"on": [{"events": "mousedown", "update": "copy('projection')"}]
},
{
"name": "start",
"value": null,
"on": [{"events": "mousedown", "update": "invert(cloned, xy())"}]
},
{
"name": "drag",
"value": null,
"on": [
{
"events": "[mousedown, window:mouseup] > window:mousemove",
"update": "invert(cloned, xy())"
}
]
},
{
"name": "delta",
"value": null,
"on": [
{
"events": {"signal": "drag"},
"update": "[(drag[0] - start[0])*4, (start[1] - drag[1])*4]"
}
]
},
{
"name": "rotateX",
"value": 250,
"on": [{"events": {"signal": "delta"}, "update": "angles[0] + delta[0]"}]
},
{
"name": "centerY",
"value": 140,
"on": [{"events": {"signal": "delta"}, "update": "angles[1] + delta[1]"}]
}
],
"data": [
{
"name": "source_0",
"url": "data/us-10m.json",
"format": {"type": "topojson", "feature": "states"}
}
],
"projections": [
{
"name": "projection",
"scale": {"signal": "scale"},
"translate": [{"signal": "rotateX"}, {"signal": "centerY"}],
"type": "albersUsa"
}
],
"marks": [
{
"name": "marks",
"type": "shape",
"style": ["geoshape"],
"from": {"data": "source_0"},
"encode": {
"update": {"fill": {"value": "lightgray"}, "stroke": {"value": "white"}}
},
"transform": [{"type": "geoshape", "projection": "projection"}]
}
]
}

extra bag information is missing in the flight offer price response

I'm testing self-service APIs. I wonder if this is a bug:
I make a search request, and the response contains the extra bag information in the flight-offer/price/additionalServices
Then I make the offer price request by adding include=bags parameter in the path of Flight Offers Price API.
However there is no any bags information in the response, neither in the offer/price/additionalServices, nor in the included/.
I still try to create order by adding the extra bag. So I use the extra bag information that I got at step 1 (search response). And the order is created successfully.
It seems that the extra bag information is missing in step 2 (response of flight offer price), is it a bug?
Here is an example of my test to reproduce the issue:
search request
{
"currencyCode": "EUR",
"originDestinations": [
{
"id": "1",
"originLocationCode": "PAR",
"destinationLocationCode": "NYC",
"departureDateTimeRange": {
"date": "2020-08-20",
"time": "10:00:00"
}
}
],
"travelers": [
{
"id": "1",
"travelerType": "ADULT"
}
],
"sources": [
"GDS"
],
"searchCriteria": {
"maxFlightOffers": 3
}
}
Then I select the second offer in the response to make a offer price request using include=bags parameter
{
"type": "flight-offer",
"id": "2",
"source": "GDS",
"instantTicketingRequired": false,
"nonHomogeneous": false,
"oneWay": false,
"lastTicketingDate": "2020-08-13",
"numberOfBookableSeats": 8,
"itineraries": [
{
"duration": "PT8H15M",
"segments": [
{
"departure": {
"iataCode": "ORY",
"terminal": "4",
"at": "2020-08-20T19:45:00"
},
"arrival": {
"iataCode": "EWR",
"terminal": "B",
"at": "2020-08-20T22:00:00"
},
"carrierCode": "TX",
"number": "6720",
"aircraft": {
"code": "359"
},
"operating": {
"carrierCode": "BF"
},
"duration": "PT8H15M",
"id": "3",
"numberOfStops": 0,
"blacklistedInEU": false
}
]
}
],
"price": {
"currency": "EUR",
"total": "149.44",
"base": "41.00",
"fees": [
{
"amount": "0.00",
"type": "SUPPLIER"
},
{
"amount": "0.00",
"type": "TICKETING"
}
],
"grandTotal": "149.44",
"additionalServices": [
{
"amount": "70.00",
"type": "CHECKED_BAGS"
}
]
},
"pricingOptions": {
"fareType": [
"PUBLISHED"
],
"includedCheckedBagsOnly": false
},
"validatingAirlineCodes": [
"TX"
],
"travelerPricings": [
{
"travelerId": "1",
"fareOption": "STANDARD",
"travelerType": "ADULT",
"price": {
"currency": "EUR",
"total": "149.44",
"base": "41.00"
},
"fareDetailsBySegment": [
{
"segmentId": "3",
"cabin": "ECONOMY",
"fareBasis": "ULBCOWFR",
"brandedFare": "EBASIC",
"class": "U",
"includedCheckedBags": {
"quantity": 0
}
}
]
}
]
}
There is no extra bag in the response.
Thanks

Nested flatten in IF statement; re-keying in multi layer flatten

Current Query:
with
report as (
select * from Report_Data
where type = 'pnl'
and (created_at > '2020-01-01' or updated_at > '2020-01-01')
),
flattened as (
select
report.company_ID as "CID",
report.type,
report.from_date as "Report_Date",
f.*
--f.value:"title"
from report,
lateral flatten(input =>prepared:profitAndLoss:report:sections) f
--,lateral flatten(input =>f.value)f1
)
select * from flattened where CID = 908 limit 100;
Current Output for f:
[
{
"rows": [
{
"emphasize": false,
"name": "Product Sales",
"values": [
{
"rawValue": 19889.16,
"value": "19,889"
},
{
"rawValue": 56181.94,
"value": "56,182"
}
]
},
{
"emphasize": false,
"name": "Credits from Vendors",
"values": [
{
"rawValue": 38,
"value": "38"
},
{
"rawValue": 47.16,
"value": "47"
}
]
},
{
"emphasize": false,
"name": "Sales - PayPal",
"values": [
{
"rawValue": 0,
"value": "0"
},
{
"rawValue": 275,
"value": "275"
}
]
},
{
"emphasize": false,
"name": "Sales Returns and Allowances",
"values": [
{
"rawValue": -379.28,
"value": "(379)"
},
{
"rawValue": -941.78,
"value": "(942)"
}
]
}
],
"summary": {
"emphasize": false,
"name": "Total Revenue",
"values": [
{
"rawValue": 19547.88,
"value": "19,548"
},
{
"rawValue": 55562.32,
"value": "55,562"
}
]
},
"title": "Revenue"
},
{
"rows": [
{
"emphasize": false,
"name": "Product Costs",
"values": [
{
"rawValue": 9857.22,
"value": "9,857"
},
{
"rawValue": 31907.32,
"value": "31,907"
}
]
},
{
"emphasize": false,
"name": "Supplies",
"values": [
{
"rawValue": 0,
"value": "0"
},
{
"rawValue": 109.92,
"value": "110"
}
]
}
],
"summary": {
"emphasize": false,
"name": "Total Cost of Sales",
"values": [
{
"rawValue": 9857.22,
"value": "9,857"
},
{
"rawValue": 32017.24,
"value": "32,017"
}
]
},
"title": "Less Cost of Sales"
},
{
"rows": [
{
"emphasize": true,
"name": "Gross Profit",
"values": [
{
"rawValue": 9690.66,
"value": "9,691"
},
{
"rawValue": 23545.08,
"value": "23,545"
}
]
}
],
"summary": {
"name": "",
"values": []
},
"title": ""
},
{
"rows": [
{
"emphasize": false,
"name": "Advertising & Marketing",
"values": [
{
"rawValue": 100,
"value": "100"
},
{
"rawValue": 100,
"value": "100"
}
]
},
{
"emphasize": false,
"name": "Advertising Expenses",
"values": [
{
"rawValue": 22,
"value": "22"
},
{
"rawValue": 689,
"value": "689"
}
]
},
{
"emphasize": false,
"name": "Bank Fees",
"values": [
{
"rawValue": 53,
"value": "53"
},
{
"rawValue": 53,
"value": "53"
}
]
},
{
"emphasize": false,
"name": "Business Telephone and Internet",
"values": [
{
"rawValue": 10.08,
"value": "10"
},
{
"rawValue": 30.24,
"value": "30"
}
]
},
{
"emphasize": false,
"name": "Charitable Contributions",
"values": [
{
"rawValue": 0,
"value": "0"
},
{
"rawValue": -81.89,
"value": "(82)"
}
]
},
{
"emphasize": false,
"name": "Computer and Software Expense",
"values": [
{
"rawValue": 20,
"value": "20"
},
{
"rawValue": 20,
"value": "20"
}
]
},
{
"emphasize": false,
"name": "Dues and Subscriptions",
"values": [
{
"rawValue": 0.99,
"value": "1"
},
{
"rawValue": 135.99,
"value": "136"
}
]
},
{
"emphasize": false,
"name": "Fees and Licenses",
"values": [
{
"rawValue": 0,
"value": "0"
},
{
"rawValue": 50,
"value": "50"
}
]
},
{
"emphasize": false,
"name": "Insurance Expense - General Liability",
"values": [
{
"rawValue": 101.6,
"value": "102"
},
{
"rawValue": 304.8,
"value": "305"
}
]
},
{
"emphasize": false,
"name": "Legal & Professional",
"values": [
{
"rawValue": 200,
"value": "200"
},
{
"rawValue": 600,
"value": "600"
}
]
},
{
"emphasize": false,
"name": "Merchant Account Fees",
"values": [
{
"rawValue": 444.91,
"value": "445"
},
{
"rawValue": 1221.71,
"value": "1,222"
}
]
},
{
"emphasize": false,
"name": "Office Expenses",
"values": [
{
"rawValue": 169.66,
"value": "170"
},
{
"rawValue": 988.42,
"value": "988"
}
]
},
{
"emphasize": false,
"name": "Payroll Processing Fee",
"values": [
{
"rawValue": 0,
"value": "0"
},
{
"rawValue": 0.45,
"value": "0"
}
]
},
{
"emphasize": false,
"name": "Rent",
"values": [
{
"rawValue": 1500,
"value": "1,500"
},
{
"rawValue": 6000,
"value": "6,000"
}
]
},
{
"emphasize": false,
"name": "Taxes",
"values": [
{
"rawValue": 0,
"value": "0"
},
{
"rawValue": 3000,
"value": "3,000"
}
]
},
{
"emphasize": false,
"name": "Travel",
"values": [
{
"rawValue": 0,
"value": "0"
},
{
"rawValue": 194.35,
"value": "194"
}
]
},
{
"emphasize": false,
"name": "Utilities",
"values": [
{
"rawValue": 559.59,
"value": "560"
},
{
"rawValue": 1769.63,
"value": "1,770"
}
]
}
],
"summary": {
"emphasize": false,
"name": "Total Operating Expenses",
"values": [
{
"rawValue": 3181.83,
"value": "3,182"
},
{
"rawValue": 15075.7,
"value": "15,076"
}
]
},
"title": "Operating Expenses"
},
{
"rows": [
{
"emphasize": false,
"name": "Operating Income / (Loss)",
"values": [
{
"rawValue": 6508.83,
"value": "6,509"
},
{
"rawValue": 8469.38,
"value": "8,469"
}
]
}
],
"summary": {
"name": "",
"values": []
},
"title": ""
},
{
"rows": [
{
"emphasize": false,
"name": "Interest",
"values": [
{
"rawValue": -85.44,
"value": "(85)"
},
{
"rawValue": -434.74,
"value": "(435)"
}
]
},
{
"emphasize": false,
"name": "Interest Income",
"values": [
{
"rawValue": 0.57,
"value": "1"
},
{
"rawValue": 1.24,
"value": "1"
}
]
},
{
"emphasize": false,
"name": "Other Income",
"values": [
{
"rawValue": 0,
"value": "0"
},
{
"rawValue": 100,
"value": "100"
}
]
}
],
"summary": {
"emphasize": false,
"name": "Total Other Income and Expense",
"values": [
{
"rawValue": -84.87,
"value": "(85)"
},
{
"rawValue": -333.5,
"value": "(334)"
}
]
},
"title": "Other Income and Expense"
},
{
"rows": [
{
"emphasize": true,
"name": "Net Income / (Loss) before Tax",
"values": [
{
"rawValue": 6423.96,
"value": "6,424"
},
{
"rawValue": 8135.88,
"value": "8,136"
}
]
}
],
"summary": {
"name": "",
"values": []
},
"title": ""
},
{
"rows": [
{
"emphasize": false,
"name": "Net Income",
"values": [
{
"rawValue": 6423.96,
"value": "6,424"
},
{
"rawValue": 8135.88,
"value": "8,136"
}
]
}
],
"summary": {
"name": "",
"values": []
},
"title": ""
},
{
"rows": [
{
"emphasize": false,
"name": "Total Comprehensive Income",
"values": [
{
"rawValue": 6423.96,
"value": "6,424"
},
{
"rawValue": 8135.88,
"value": "8,136"
}
]
}
],
"summary": {
"name": "",
"values": []
},
"title": ""
}
]
https://codebeautify.org/jsonviewer
Recommend c/p JSON into above link and selecting "tree viewer" to follow along with my navigation references
Problem:
Snowflake/ASNI SQL:
For each index in the array I need to evaluate a logical function that checks the "title" key, and if the value of the "title" key is X (for the sake of this exercise let's choose "Revenue"), return the "name" and "values" for each index of the "rows" key. Under rows:values you have 2 Values. They need to be re-keyed to MTD and YTD. They are consistently stored as [0]:MTD and [1]:YTD. I want these new keys to appear in a column I have named "periodicity." I know this is all one tricky flattening problem in snowflake, but I struggled with it all weekend in many different iterations and would like to see if someone can give it a shot. Thanks for the help!
Desired Output:
CID, TYPE, REPORT_DATE, "Title" Key, rows:Name as "Name", periodicity, rows:values:[0]:rawValue
EDIT: Sample output columns with values:
CID TYPE REPORT_DATE "Title" Key rows:Name as "Name"
47 PNL 2020-01-01 REVENUE "Sales - PayPal"
periodicity rows:values:[0]:rawValue
"MTD" 0
So the flatten is not too hard. If you take it step at a time:
with random_json as (
select '2020-05-27'::date as report_date, parse_json('[
{
"rows": [
{
"emphasize": false,
"name": "Product Sales",
"values": [
{
"rawValue": 19889.16,
"value": "19,889"
},
{
"rawValue": 56181.94,
"value": "56,182"
}
]
},
{
"emphasize": false,
"name": "Credits from Vendors",
"values": [
{
"rawValue": 38,
"value": "38"
},
{
"rawValue": 47.16,
"value": "47"
}
]
},
{
"emphasize": false,
"name": "Sales - PayPal",
"values": [
{
"rawValue": 0,
"value": "0"
},
{
"rawValue": 275,
"value": "275"
}
]
},
{
"emphasize": false,
"name": "Sales Returns and Allowances",
"values": [
{
"rawValue": -379.28,
"value": "(379)"
},
{
"rawValue": -941.78,
"value": "(942)"
}
]
}
],
"summary": {
"emphasize": false,
"name": "Total Revenue",
"values": [
{
"rawValue": 19547.88,
"value": "19,548"
},
{
"rawValue": 55562.32,
"value": "55,562"
}
]
},
"title": "Revenue"
},
{
"rows": [
{
"emphasize": false,
"name": "Product Costs",
"values": [
{
"rawValue": 9857.22,
"value": "9,857"
},
{
"rawValue": 31907.32,
"value": "31,907"
}
]
},
{
"emphasize": false,
"name": "Supplies",
"values": [
{
"rawValue": 0,
"value": "0"
},
{
"rawValue": 109.92,
"value": "110"
}
]
}
],
"summary": {
"emphasize": false,
"name": "Total Cost of Sales",
"values": [
{
"rawValue": 9857.22,
"value": "9,857"
},
{
"rawValue": 32017.24,
"value": "32,017"
}
]
},
"title": "Less Cost of Sales"
}
]') as json
), flatten_a AS (
select
r.report_date
,f.value:rows as r_rows
,f.value:summary as r_summary
,f.value:title as r_title
from random_json r
,lateral flatten(input=>r.json) f
), flatten_b AS (
select a.*
, f.value:name as rr_name
, f.value:values as rr_values
from flatten_a a
,lateral flatten(input=>a.r_rows) f
)
select b.report_date
,b.r_title as title_key
,b.rr_name as name
,case when f.index =0 then 'MTD' when f.index=1 then 'YTD' else 'WTF' end as periodicity
, f.value:rawValue raw_value
from flatten_b b
,lateral flatten(input=>b.rr_values) f;
gives:
REPORT_DATE TITLE_KEY NAME PERIODICITY RAW_VALUE
2020-05-27 "Revenue" "Product Sales" MTD 19889.16
2020-05-27 "Revenue" "Product Sales" YTD 56181.94
2020-05-27 "Revenue" "Credits from Vendors" MTD 38
2020-05-27 "Revenue" "Credits from Vendors" YTD 47.16
2020-05-27 "Revenue" "Sales - PayPal" MTD 0
2020-05-27 "Revenue" "Sales - PayPal" YTD 275
2020-05-27 "Revenue" "Sales Returns and Allowances" MTD -379.28
2020-05-27 "Revenue" "Sales Returns and Allowances" YTD -941.78
2020-05-27 "Less Cost of Sales" "Product Costs" MTD 9857.22
2020-05-27 "Less Cost of Sales" "Product Costs" YTD 31907.32
2020-05-27 "Less Cost of Sales" "Supplies" MTD 0
2020-05-27 "Less Cost of Sales" "Supplies" YTD 109.92
if what you mention in the first sentence as only wanting the above rows for "Revenue" make the results set a CTE also, and left join to your "report" and ON filter for revenue.

Brushing/linking in vega (not vega-lite)

I'm trying to brush/link two plots in vega, more specifically a node-link diagram and a couple of scatterplots. Based on how dragging works with signals in the node-link diagram I did get quite far, but not far enough...
For the sake of simplicity, I'll provide a little test code here using just two scatterplots:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"padding": 0,
"autosize": "none",
"width": 800,
"height": 400,
"signals": [
{ "description": "Any datapoint is activated",
"name": "datapoint_is_activated", "value": false,
"on": [
{
"events": "symbol:mouseover",
"update": "true"
},
{
"events": "symbol:mouseout",
"update": "false"
}
]
},
{ "description": "Active datapoint",
"name": "activated_datapoint", "value": null,
"on": [
{
"events": "symbol:mouseover",
"update": "item()"
},
{
"events": "symbol:mouseout",
"update": "null"
}
]
}
],
"data": [
{
"name": "table",
"values": [
{"name": "point A", "a": 1, "b": 2, "c": 3},
{"name": "point B", "a": 4, "b": 5, "c": 6},
{"name": "point C", "a": 9, "b": 8, "c": 7}
]
}
],
"scales": [
{ "name": "xscale",
"type": "linear",
"domain": [0,10],
"range": [0,200]
},
{ "name": "yscale",
"type": "linear",
"domain": [0,10],
"range": [0,200]
}
],
"layout": {"padding": 20},
"marks": [
{ "name": "plot1",
"type": "group",
"axes": [
{"orient": "bottom", "scale": "xscale"},
{"orient": "right", "scale": "yscale"}
],
"marks": [
{
"type": "symbol",
"from": {"data": "table"},
"encode": {
"enter": {
"x": {"field": "a", "scale": "xscale"},
"y": {"field": "b", "scale": "yscale"},
"tooltip": {"field": "name"}
},
"update": {
"size": {"value": 100},
"fill": {"value": "grey"}
}
}
}
]
},
{ "name": "plot2",
"type": "group",
"axes": [
{"orient": "bottom", "scale": "xscale"},
{"orient": "right", "scale": "yscale"}
],
"marks": [
{
"type": "symbol",
"from": {"data": "table"},
"on": [
{
"trigger": "datapoint_is_activated",
"modify": "activated_datapoint",
"values": "{fill: \"red\"}"
},
{
"trigger": "!datapoint_is_activated",
"modify": "activated_datapoint",
"values": "{fill: \"grey\"}"
}
],
"encode": {
"enter": {
"x": {"field": "a", "scale": "xscale"},
"y": {"field": "c", "scale": "yscale"},
"size": {"value": 100},
"tooltip": {"field": "name"}
},
"update": {
"fill": {"value": "grey"}
}
}
}
]
}
]
}
The resulting image looks like this:
The idea is that hovering over a datapoint in the left plot will highlight the corresponding datapoint in the right plot. I know this is straightforward in vega-lite, but that does not (yet) support node-link diagrams. Hence: vega.
My approach in the code is to:
create a signal in the outer scope that tracks (a) if there is a point activated, and (b) which point this is
in plot 2 to have a trigger that takes the activated datapoint and changes its colour to 'red'.
I have an inkling feeling that it has to do with my definition of the modify and values part, but I can't figure it out.
Any help very much appreciated!
Thank you,
jan.
After a lot of trial and error, I did find a way to do this. Instead of using a trigger (which I believe would be the canonical way of doing this), I merely use a test in the fill section: datapoint_is_activated && datum === activated_datapoint.datum. See code and image below.
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"padding": 0,
"autosize": "none",
"width": 800,
"height": 400,
"signals": [
{ "description": "Any datapoint is activated",
"name": "datapoint_is_activated", "value": false,
"on": [
{
"events": "symbol:mouseover",
"update": "true"
},
{
"events": "symbol:mouseout",
"update": "false"
}
]
},
{ "description": "Active datapoint",
"name": "activated_datapoint", "value": null,
"on": [
{
"events": "symbol:mouseover",
"update": "item()"
},
{
"events": "symbol:mouseout",
"update": "null"
}
]
}
],
"data": [
{
"name": "table",
"values": [
{"name": "point A", "a": 2, "b": 2, "c": 4},
{"name": "point B", "a": 4, "b": 5, "c": 6},
{"name": "point C", "a": 5, "b": 3, "c": 5}
]
}
],
"scales": [
{ "name": "xscale",
"type": "linear",
"domain": [0,10],
"range": [0,200]
},
{ "name": "yscale",
"type": "linear",
"domain": [0,10],
"range": [0,200]
}
],
"layout": {"padding": 20},
"marks": [
{ "name": "plot1",
"type": "group",
"axes": [
{"orient": "bottom", "scale": "xscale"},
{"orient": "right", "scale": "yscale"}
],
"marks": [
{
"type": "symbol",
"from": {"data": "table"},
"encode": {
"enter": {
"x": {"field": "a", "scale": "xscale"},
"y": {"field": "b", "scale": "yscale"},
"tooltip": {"field": "name"},
"size": {"value": 200}
},
"update": {
"fill": [
{"test": "datapoint_is_activated && datum === activated_datapoint.datum",
"value": "red"},
{"value": "lightgrey"}
]
}
}
}
]
},
{ "name": "plot2",
"type": "group",
"axes": [
{"orient": "bottom", "scale": "xscale"},
{"orient": "right", "scale": "yscale"}
],
"marks": [
{
"type": "symbol",
"from": {"data": "table"},
"encode": {
"enter": {
"x": {"field": "a", "scale": "xscale"},
"y": {"field": "c", "scale": "yscale"},
"size": {"value": 200},
"tooltip": {"field": "name"}
},
"update": {
"fill": [
{"test": "datapoint_is_activated && datum === activated_datapoint.datum",
"value": "red"},
{"value": "lightgrey"}
]
}
}
}
]
}
]
}

How do I use the Google Civic Information API to retrieve members of Congress for a given location?

I've tried using the civicinfo.representatives.representativeInfoByAddress endpoint in the API explorer (https://developers.google.com/apis-explorer/?hl=en_US#p/civicinfo/v2/civicinfo.representatives.representativeInfoByAddress).
Here's my problem: That endpoint returns all state, federal, and local offices EXCEPT the U.S. House of Representatives! I can see the governor, senators, state senators, but NOT members of Congress. I can't find anything in the documentation to explain why this blatantly important data is being omitted, nor can I find any alternative sources (that are actually current) for this data.
Why is Google withholding the Congressional data and how do I get it? That's the ONE THING I need from this API and it seems to be missing from the results. I've tried playing with the parameters and whatnot but I can't find that data.
There has to be a way to find this information. In the Google API Explorer (see above link), try entering "WA" for the "address" field and leave everything else blank (setting the next one to TRUE makes no difference and the others are just filters). Here's the data that's returned:
{
"kind": "civicinfo#representativeInfoResponse",
"normalizedInput": {
"line1": "",
"city": "",
"state": "WA",
"zip": ""
},
"divisions": {
"ocd-division/country:us": {
"name": "United States",
"officeIndices": [
0,
1
]
},
"ocd-division/country:us/state:wa": {
"name": "Washington",
"officeIndices": [
2,
3,
4,
5,
6,
7,
8,
9,
10,
11
]
}
},
"offices": [
{
"name": "President of the United States",
"divisionId": "ocd-division/country:us",
"levels": [
"country"
],
"roles": [
"headOfState",
"headOfGovernment"
],
"officialIndices": [
0
]
},
{
"name": "Vice-President of the United States",
"divisionId": "ocd-division/country:us",
"levels": [
"country"
],
"roles": [
"deputyHeadOfGovernment"
],
"officialIndices": [
1
]
},
{
"name": "United States Senate",
"divisionId": "ocd-division/country:us/state:wa",
"levels": [
"country"
],
"roles": [
"legislatorUpperBody"
],
"officialIndices": [
2,
3
]
},
{
"name": "Governor",
"divisionId": "ocd-division/country:us/state:wa",
"levels": [
"administrativeArea1"
],
"roles": [
"headOfGovernment"
],
"officialIndices": [
4
]
},
{
"name": "Lieutenant Governor",
"divisionId": "ocd-division/country:us/state:wa",
"levels": [
"administrativeArea1"
],
"roles": [
"deputyHeadOfGovernment"
],
"officialIndices": [
5
]
},
{
"name": "State Auditor",
"divisionId": "ocd-division/country:us/state:wa",
"officialIndices": [
6
]
},
{
"name": "State Treasurer",
"divisionId": "ocd-division/country:us/state:wa",
"officialIndices": [
7
]
},
{
"name": "Attorney General",
"divisionId": "ocd-division/country:us/state:wa",
"officialIndices": [
8
]
},
{
"name": "Secretary of State",
"divisionId": "ocd-division/country:us/state:wa",
"officialIndices": [
9
]
},
{
"name": "Insurance Commissioner",
"divisionId": "ocd-division/country:us/state:wa",
"officialIndices": [
10
]
},
{
"name": "Commissioner of Public Lands",
"divisionId": "ocd-division/country:us/state:wa",
"officialIndices": [
11
]
},
{
"name": "State Superintendent of Public Instruction",
"divisionId": "ocd-division/country:us/state:wa",
"officialIndices": [
12
]
}
],
"officials": [
{
"name": "Donald J. Trump",
"address": [
{
"line1": "The White House",
"line2": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC",
"zip": "20500"
}
],
"party": "Republican",
"phones": [
"(202) 456-1111"
],
"urls": [
"http://www.whitehouse.gov/"
],
"photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/PE%20Color.jpg",
"channels": [
{
"type": "GooglePlus",
"id": "+whitehouse"
},
{
"type": "Facebook",
"id": "whitehouse"
},
{
"type": "Twitter",
"id": "potus"
},
{
"type": "YouTube",
"id": "whitehouse"
}
]
},
{
"name": "Mike Pence",
"address": [
{
"line1": "The White House",
"line2": "1600 Pennsylvania Avenue NW",
"city": "Washington",
"state": "DC",
"zip": "20500"
}
],
"party": "Republican",
"phones": [
"(202) 456-1111"
],
"urls": [
"http://www.whitehouse.gov/"
],
"photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/VPE%20Color.jpg",
"channels": [
{
"type": "GooglePlus",
"id": "+whitehouse"
},
{
"type": "Facebook",
"id": "whitehouse"
},
{
"type": "Twitter",
"id": "VP"
}
]
},
{
"name": "Maria Cantwell",
"address": [
{
"line1": "511 Hart Senate Office Building",
"city": "Washington",
"state": "DC",
"zip": "20510"
}
],
"party": "Democratic",
"phones": [
"(202) 224-3441"
],
"urls": [
"https://www.cantwell.senate.gov/"
],
"photoUrl": "http://bioguide.congress.gov/bioguide/photo/C/C000127.jpg",
"channels": [
{
"type": "Facebook",
"id": "senatorcantwell"
},
{
"type": "Twitter",
"id": "senatorcantwell"
},
{
"type": "YouTube",
"id": "SenatorCantwell"
}
]
},
{
"name": "Patty Murray",
"address": [
{
"line1": "154 Russell Senate Office Building",
"city": "Washington",
"state": "DC",
"zip": "20510"
}
],
"party": "Democratic",
"phones": [
"(202) 224-2621"
],
"urls": [
"http://www.murray.senate.gov/public/"
],
"photoUrl": "http://bioguide.congress.gov/bioguide/photo/M/M001111.jpg",
"channels": [
{
"type": "GooglePlus",
"id": "+pattymurray"
},
{
"type": "Twitter",
"id": "pattymurray"
},
{
"type": "YouTube",
"id": "SenatorPattyMurray"
},
{
"type": "Facebook",
"id": "pattymurray"
},
{
"type": "YouTube",
"id": "pattymurray"
}
]
},
{
"name": "Jay Inslee",
"address": [
{
"line1": "PO Box 40002",
"city": "Olympia",
"state": "WA",
"zip": "98504"
}
],
"party": "Democratic",
"phones": [
"(360) 902-4111"
],
"urls": [
"http://www.governor.wa.gov/"
],
"photoUrl": "http://www.governor.wa.gov/sites/default/files/images/720px-for-web_0.jpg",
"emails": [
"Governor.JayInslee#governor.wa.gov"
],
"channels": [
{
"type": "Facebook",
"id": "WaStateGov"
},
{
"type": "Twitter",
"id": "GovInslee"
},
{
"type": "YouTube",
"id": "UCJhWBqWVdVnPro7tx2t7j3w"
}
]
},
{
"name": "Cyrus Habib",
"address": [
{
"line1": "PO Box 40400",
"city": "Olympia",
"state": "WA",
"zip": "98504"
}
],
"party": "Democratic",
"phones": [
"(360) 786-7700"
],
"urls": [
"http://www.ltgov.wa.gov/"
],
"photoUrl": "http://www.ltgov.wa.gov/wp-content/uploads/2017/01/Senator-Habib-2015_CROPPED-225x300.jpg",
"emails": [
"ltgov#ltgov.wa.gov"
],
"channels": [
{
"type": "Twitter",
"id": "waltgov"
},
{
"type": "Facebook",
"id": "Lt-Governor-Cyrus-Habib-347384975292728"
}
]
},
{
"name": "Pat (Patrice) McCarthy",
"address": [
{
"line1": "Insurance Building Capitol Campus",
"line2": "302 Sid Snyder Avenue SW",
"city": "Olympia",
"state": "WA",
"zip": "98504"
}
],
"party": "Democratic",
"phones": [
"(360) 902-0370"
]
},
{
"name": "Duane Davidson",
"address": [
{
"line1": "PO Box 40200",
"city": "Olympia",
"state": "WA",
"zip": "98504"
}
],
"party": "Republican",
"phones": [
"(360) 902-9001"
]
},
{
"name": "Bob Ferguson",
"address": [
{
"line1": "PO Box 40100",
"city": "Olympia",
"state": "WA",
"zip": "98504"
}
],
"party": "Democratic",
"phones": [
"(360) 753-6200"
],
"urls": [
"http://www.atg.wa.gov/"
],
"channels": [
{
"type": "Facebook",
"id": "WAStateAttorneyGeneral"
},
{
"type": "Twitter",
"id": "AGOWA"
}
]
},
{
"name": "Kim Wyman",
"address": [
{
"line1": "PO Box 40220",
"city": "Olympia",
"state": "WA",
"zip": "98504"
}
],
"party": "Republican",
"phones": [
"(360) 902-4151"
],
"urls": [
"http://www.sos.wa.gov/"
],
"emails": [
"kim.wyman#sos.wa.gov"
],
"channels": [
{
"type": "Facebook",
"id": "WaSecretaryOfState"
},
{
"type": "Twitter",
"id": "secstatewa"
}
]
},
{
"name": "Mike Kreidler",
"party": "Democratic",
"phones": [
"(360) 725-7000"
],
"urls": [
"http://www.insurance.wa.gov/"
],
"channels": [
{
"type": "Facebook",
"id": "wsoic"
},
{
"type": "Twitter",
"id": "WAinsuranceblog"
}
]
},
{
"name": "Hilary Franz",
"address": [
{
"line1": "PO Box 47000",
"city": "Olympia",
"state": "WA",
"zip": "98504"
}
],
"party": "Democratic",
"phones": [
"(360) 902-1000"
]
},
{
"name": "Chris Reykdal",
"address": [
{
"line1": "Mail stop: 47200 Old Capitol Building P.O. Box 47200",
"city": "Olympia",
"state": "WA",
"zip": "98504"
}
],
"party": "Nonpartisan",
"phones": [
"(360) 725-6115"
]
}
]
}
Now, do a text search for "Adam Smith" in that JSON. He's a current member of Congress in WA. You'll notice that string is not present, nor are any other members of Congress, nor can I find any reference links in the return to look them up.
What am I missing?? It seems utterly insane to me that everything is included there except members of the U.S. House (but federal and state Senates are included). That means it's possible that the data is available somehow but I'm just not figuring it out. Can anybody help?
Thanks!
This is a couple of months late but you need to specify the to look for the roles legislatorUpperBody and legislatorLowerBody.
If you just want to have these two peices of infomation try running the query
https://www.googleapis.com/civicinfo/v2/representatives?address=[address]&levels=country&roles=legislatorUpperBody&roles=legislatorLowerBody&key=[api_key]
Instead of returning all possible results for representatives for a given area, the API seems to only return exact matches.
Assuming 2 requests that both use levels=country&roles=legislatorLowerBody.
I get 0 results using the address Boston, MA.
I get the proper representative using the address 10 Summer St, Boston, MA.
Congressional districts can be pretty specific. In some cases the street number along the same street will dictate one district versus another.