Postgres在jsonb嵌套数组中找到

时间:2020-01-15 02:43:00

标签: postgresql jsonb

我有一种情况,当我的数据放入jsonb的嵌套数组中以查找值时,我必须执行多个JSONB_ARRAY_ELEMENTS,这很昂贵,而且需要很多嵌套代码。

json文件具有国家和城市内部的大洲。 我需要访问城市值。

  1. 有没有办法使此查询更简单,更快捷?
  2. 我试图使用JSON_EXTRACT_PATH解决它,但为了进入数组,但我需要索引。
<div class="bgimg">
  <div class="topleft">
    <p>Logo</p>
  </div>
  <div class="middle">
    <h1>COMING SOON</h1>
    <hr>
    <p>A week ago a friend invited a couple of other couples over for dinner. Eventually, the food (but not the wine) was cleared off the table for what turned out to be some fierce Scrabbling. Heeding the strategy of going for the shorter, more valuable word over the longer cheaper word, our final play was “Bon,” which–as luck would have it!–happens to be a Japanese Buddhist festival, and not, as I had originally asserted while laying the tiles on the board, one half of a chocolate-covered cherry treat. Anyway, the strategy worked. My team only lost by 53 points instead of 58.

Just the day before, our host had written of the challenges of writing short. In journalism–my friend’s chosen trade, and mostly my own, too–Mark Twain’s observation undoubtedly applies: “I didn’t have time to write a short letter, so I wrote a long one instead.” The principle holds across genres, in letters, reporting, and other writing. It’s harder to be concise than to blather. (Full disclosure, this blog post will clock in at a blather-esque 803 words.) Good writing is boiled down, not baked full of air like a souffl??. No matter how yummy souffl??s may be. Which they are. Yummy like a Grisham novel.

Lately, I’ve been noticing how my sentences have a tendency to keep going when I write them onscreen. This goes for concentrated writing as well as correspondence. (Twain probably believed that correspondence, in an ideal world, also demands concentration. But he never used email.) Last week I caught myself packing four conjunctions into a three-line sentence in an email. That’s inexcusable. Since then, I have tried to eschew conjunctions whenever possible. Gone are the commas, the and’s, but’s, and so’s; in are staccato declaratives. Better to read like bad Hemingway than bad Faulkner.

Length–as we all know, and for lack of a more original or effective way of saying it–matters. But (ahem), it’s also a matter of how you use it. Style and length are technically two different things.

Try putting some prose onscreen, though, and they mix themselves up pretty quickly. This has much to do with the time constraints we claim to feel in the digital age. We don’t have time to compose letters and post them anymore–much less pay postage, what with all the banks kinda-sorta losing our money these days–so we blast a few emails. We don’t have time to talk, so we text. We don’t have time to text to specific people, so we update our Facebook status. We don’t have time to write essays, so we blog.

I’m less interested by the superficial reduction of words–i.e. the always charming imho or c u l8r–than the genres in which those communications occur: blogs, texts, tweets, emails. All these interstitial communiques, do they really reflect super brevity that would make Twain proud? Or do they just reflect poorly stylized writing that desperately seeks a clearer form?

I rather think the latter. Clive Thompson wrote last month in the NYT Magazine that constant digital updates, after a day, can begin “to feel like a short story; follow it for a month, and it’s a novel.” He was right to see the bits as part of a larger whole. The words now flying through our digital pipes & ether more or less tend to resemble parts of bigger units, perhaps even familiar genres. But stories and novels have definite conclusions; they also have conventional lengths. Quick, how long is the conventional blog, when you add up all of its posts and comments? How long is the longest email thread you send back and forth on a single topic?

Most important: What exactly are we writing when we’re doing all of this writing? I won’t pretend to coin a whole new term here; I still think the best we can muster is a more fitting analogue. And if we must find an analogue in an existing literary unit, I propose the paragraph. Our constant writing has begun to feel like a neverending digital paragraph. Not a tight, stabbing paragraph from The Sun Also Rises or even a graceful, sometimes-slinking, sometimes-soaring paragraph from Absalom! Absalom!, I mean a convoluted, haphazard, meandering paragraph, something like Kerouac’s original draft of On the Road–only taped together by bytes. And 1 percent as interesting.

Paragraphs, particularly those that wrap from one page to the next, inherently possess a necessary suspension that tightens the reader’s focus yet breaks down the narrative into digestable sections. Just like emails or blogs or texts. The mental questions while reading all of these feel the same:

“Is this the last line or is there more?”

“Is the writer really trying to say something here, or just setting up a larger point?”

“Does this part have the information I’m looking for?”</p>
  </div>
  <div class="bottomleft">
    <p>Some text</p>
  </div>
</div>

看到我的嵌套查询?看起来很丑,我可以使用WITH mydata AS ( SELECT ' { "continents":[ { "name":"America", "area":43316000, "countries":[ { "country_name":"Canada", "capital":"Toronto", "cities":[ { "city_name":"Ontario", "population":2393933 }, { "city_name":"Quebec", "population":12332 } ] }, { "country_name":"Brazil", "capital":"Brasilia", "cities":[ { "city_name":"Sao Paolo", "population":34534534 }, { "city_name":"Rio", "population":445345 } ] } ] }, { "name":"Europa", "area":10530751, "countries":[ { "country_name":"Switzerland", "capital":"Zurich", "cities":[ { "city_name":"Ginebra", "population":4564565 }, { "city_name":"Basilea", "population":4564533 } ] }, { "country_name":"Norway", "capital":"Oslo", "cities":[ { "city_name":"Oslo", "population":3243534 }, { "city_name":"Steinkjer", "population":4565465 } ] } ] } ] } '::JSONB AS data_column ) SELECT cit.city->>'city_name' AS city, (cit.city->>'population')::INTEGER AS population FROM (SELECT JSONB_ARRAY_ELEMENTS(coun.country->'cities') AS city FROM (SELECT JSONB_ARRAY_ELEMENTS(cont.continent->'countries') AS country FROM (SELECT JSONB_ARRAY_ELEMENTS(data_column->'continents') AS continent FROM mydata ) AS cont WHERE cont.continent @> '{"name":"Europa"}' ) AS coun WHERE coun.country @> '{"country_name" : "Norway"}' ) AS cit WHERE cit.city @> '{"city_name": "Oslo"}' 得到答案,但是我必须对数组索引进行硬编码。

希望你能帮助我。

谢谢。

1 个答案:

答案 0 :(得分:2)

您不需要任何嵌套,可以进行lateral queries

SELECT
  city->>'city_name' AS city,
  (city->>'population')::INTEGER AS population
FROM
  mydata,
  JSONB_ARRAY_ELEMENTS(data_column->'continents') AS continent,
  JSONB_ARRAY_ELEMENTS(continent->'countries') AS country,
  JSONB_ARRAY_ELEMENTS(country->'cities') AS city
WHERE continent ->> 'name' = 'Europa'
  AND country ->> 'country_name' = 'Norway'
  AND city ->> 'city_name' = 'Oslo';

online demo

但是,由于您提到了路径并且必须在其中指定索引,所以实际上这是Postgres 12 JSON paths的完美用例:

SELECT jsonb_path_query(data_column, '$.continents[*]?(@.name == "Europa").countries[*]?(@.country_name=="Norway").cities[*]?(@.city_name=="Oslo")') FROM mydata

online demo