JSON Toolkit

JMESPath pro začátečníky: projekce, které porazí JSONPath

Shrnutí: JMESPath přetváří dávky objektů přímočařeji než JSONPath. Tento průvodce pro začátečníky pokrývá syntaxi, projekce, pipes, vestavěné funkce a použití v AWS CLI.

Začátečník~9 min čteníPublikováno 2026-10-31Aktualizováno 2026-10-31
Titulní obrázek článku JMESPath pro začátečníky

Stručně: JSON Pointer použijte k lokalizaci podle pozice, JSONPath k filtrování nebo rekurzi a JMESPath, když potřebujete výsledek přetvořit nebo ho projektovat na příkazovém řádku; jedno známé pole nepotřebuje ani jedno.

Pokud je vaším cílem přetvořit dávku objektů do jiného tvaru, JMESPath je často přímočařejší než JSONPath. Nehraje uzly; konstruuje výsledek.

1. Co JMESPath je

JMESPath je dotazovací jazyk navržený speciálně pro JSON. Původně vznikl pro filtrování výstupu AWS CLI a později se rozšířil do mnoha jazyků přes implementace jako jmespath.js, jmespath.py a go-jmespath. Jeho cíl se liší od JSONPath:

  • JSONPath se soustředí na výběr množiny uzlů podle cesty a podmínky a vrací množinu uzlů;
  • JMESPath se soustředí na transformaci vstupního JSON a vrací hodnotu libovolného tvaru.

Tento rozdíl činí JMESPath obzvlášť dobrým pro projekce seznamů, přejmenování polí a ořez výsledků, například zredukování dvaceti polí z odpovědi API na tři pole, která frontend skutečně potřebuje. Pokud jste ještě nečetli základy JSONPath, začněte s Dotazovací jazyk JSONPath v praxi.

2. Základní syntaxe: od identifikátorů k indexům

JMESPath používá méně symbolů než JSONPath a čte se spíš jako extrakční výraz:

Syntaxe Význam Příklad
name Přístup ke členu objektu people
a.b Přístup k vnořeným členům store.bicycle.color
[0] Přístup k indexu pole people[0]
[-1] Přístup k poslednímu prvku people[-1]
[0:2] Slice, včetně začátku a bez konce people[0:2]
[*] Projekce seznamu people[*].name
[] Zplošťující projekce people[].tags[]
[?condition] Filtrační projekce people[?age > 18]
{key: expr} Vícenásobný výběr do hash {name: name, age: age}
[expr, expr] Vícenásobný výběr do seznamu [name, age]
| Předá levý výsledek do pravé strany people[*].age | [0]

Minimální příklad:

{
  "people": [
    { "name": "Alice", "age": 31, "city": "Shanghai" },
    { "name": "Bob", "age": 17, "city": "Beijing" }
  ]
}
people[0].name      → "Alice"
people[-1].city     → "Beijing"
people[0:2].name    → ["Alice", "Bob"]

Všimněte si, proč people[0:2].name vrací pole: slice vrací seznam a následující .name se automaticky projektuje přes každý prvek toho seznamu. To je největší rozdíl mezi JMESPath a obyčejným přístupem k objektu.

3. Projekce: přeměna jednoho seznamu na jiný

Projekce je klíčový koncept JMESPath. Funguje ve dvou krocích: vyhodnotí každý prvek seznamu a poté výsledky shromáždí do nového seznamu. Prvky, které se vyhodnotí jako null, jsou automaticky zahozeny.

people[*].name                   // ["Alice", "Bob"]
people[*].{name: name, age: age} // seznam objektů
people[?age > 18].name           // ["Alice"]

Druhý řádek je typický projekční výraz: people[*].{name: name, age: age}. Přestaví každý prvek jako { "name": ..., "age": ... } a zahodí nadbytečné pole city. Ve srovnání s JSONPath, který vám dá uzly, jež pak mapujete v kódu, to ušetří jednu smyčku.

Dva druhy projekcí stojí za rozlišení:

  • [*] zachovává původní strukturu seznamu a přeskakuje nulové hodnoty;
  • [] je zplošťující projekce, která nejprve slisuje jednu úroveň vnořených seznamů, což se hodí pro výrazy jako people[].tags[], které potřebují „všechny tagy všech lidí“.

4. Pipes a vícenásobný výběr

Pipe | znamená „zastav aktuální projekci a považuj výsledek za nový vstup“. Jeho nejčastější použití je vzít index po projekci:

people[*].name | [0]           → "Alice"
people[*].age | sort(@) | [-1] → maximální věk

Bez pipe se people[*].name[0] interpretuje jako první znak každého jména, což není to, co chcete. Pipe je nejsnadněji přehlédnutelný a nejužitečnější symbol v JMESPath.

Existují dvě formy vícenásobného výběru:

// Vícenásobný výběr do hash: výsledkem je objekt
people[0].{name: name, age: age}

// Vícenásobný výběr do seznamu: výsledkem je pole
people[0].[name, age]

Vícenásobné hashe se hodí pro konstrukci pojmenovaných výsledků, zatímco vícenásobné seznamy pro poziční konzumaci. Oba lze vnořit do projekcí, ale pozor: ve vícenásobném hashi zůstává klíč, jehož hodnota je null, zatímco projekce zahodí celý null prvek.

5. Vestavěné funkce

Standard JMESPath definuje sadu funkcí. Běžné zahrnují:

Funkce Účel Příklad
length() Získat délku length(people)
sort() Seřadit hodnoty sort(people[*].age)
sort_by() Seřadit podle pole sort_by(people, &age)
max() / min() Maximum / minimum max(people[*].age)
sum() Součet hodnot sum(people[*].age)
keys() Získat klíče objektu keys(people[0])
contains() Ověřit obsažení contains(name, "Ali")
to_string() Převést na řetězec to_string(age)

Druhý argument sort_by je výraz &, který znamená „vezmi toto pole z každého prvku“:

sort_by(people, &age)[*].name

Tyto funkce nechávají JMESPath provádět jednoduchou agregaci, zatímco JSONPath je navržen jen pro výběr; sčítání a seskupování obvykle vyžadují jq nebo kód.

6. Srovnání vedle sebe s JSONPath

Dimenze JSONPath JMESPath
Primární cíl Vybrat uzly Transformovat data
Kořenový symbol $ Žádný; pište názvy polí přímo
Aktuální uzel @ @ (jen v argumentech funkcí)
Filtr [?(@.age > 18)] [?age > 18]
Zástupný znak [*] [*] nebo []
Konstrukce nových objektů Nepodporováno {name: name}
Pipes Nepodporováno |
Standard RFC 9535 JMESPath Specification

Rozhodovací vodítko v jedné větě:

  • JSONPath použijte, když potřebujete jen najít uzly odpovídající podmínce;
  • JMESPath použijte, když potřebujete výsledek přetvořit do podoby, kterou frontend očekává;
  • Nepoužívejte ani jedno, když čtete jedno známé pole; prostě přistupte k vlastnosti přímo.

Pokud výsledek dotazu musí být zapsán zpět do dokumentu, ani jeden jazyk není vhodný. Použijte JSON Pointer a patche; viz JSON Pointer, Patch a Merge Patch.

7. JMESPath v AWS CLI

Parametr --query v AWS CLI je JMESPath, což je jeho nejrozšířenější případ použití:

aws ec2 describe-instances \
  --query 'Reservations[].Instances[].{Id: InstanceId, State: State.Name, Type: InstanceType}' \
  --output table

Tento příkaz dělá tři věci: zplošťuje dva vnořené seznamy pomocí [], udrží jen tři pole pomocí vícenásobného hashe a vykreslí výsledek jako tabulku pomocí --output table. S JSONPath byste potřebovali více úrovní a nezískali byste efekt „přejmenovat a oříznout“.

Další běžné formy:

# Jen běžící instance
aws ec2 describe-instances --query 'Reservations[].Instances[?State.Name==`running`].[InstanceId,PublicIpAddress]'

# Hodnota tagu Name
aws ec2 describe-instances --query 'Reservations[].Instances[].Tags[?Key==`Name`].Value[]'

Pozor, zpětné apostrofy obklopují literály, nikoli řetězce. V AWS CLI řetězce používají jednoduché uvozovky a JSON literály zpětné apostrofy. Tento rozdíl je jednou z nejběžnějších začátečnických chyb.

8. Běžné chyby

  • Záměna [*] a []: první zachovává vnoření, druhé zplošťuje jednu úroveň a výsledné struktury jsou zcela odlišné;
  • Zapomenutá pipe: people[*].name[0] bere první znak každého jména, nikoli první jméno;
  • Psaní @ uvnitř filtru: filtry JMESPath používají názvy polí přímo, takže [?@.age > 18] je špatně;
  • Považování null za prázdný řetězec: projekce zahazují null, ale vícenásobné hashe klíč zachovávají;
  • Používání dvojitých uvozovek kolem literálů v AWS CLI: shell je nejprve expanduje a výraz přepíše.

Rada pro ladění: výraz validujte na nejmenším možném vstupu, než ho použijete na skutečná data, a v AWS CLI přidejte --output json, abyste viděli surové výsledky. Pro každodenní úpravy a formátování JSON je kombinace s Editory JSON a nástroji příkazového řádku mnohem rychlejší při lokalizaci cest polí.

Časté dotazy

Lze JMESPath a JSONPath použít společně?

Ano, ale obvykle to není nutné. Běžný přístup je oříznout malý objekt pomocí JMESPath a poté použít obyčejný přístup k vlastnostem v kódu. Pokud skutečně potřebujete lokalizovat podle cesty a poté upravit, JSONPath čte a JSON Pointer zapisuje, což je jasnější rozdělení práce.

Proč people[*].name nevrací jediný řetězec?

Protože [*] je projekce a výsledkem je vždy seznam, i když je tam jen jedna osoba. Pro jedinou hodnotu přidejte pipe a index: people[*].name | [0].

Co se stane s null uvnitř projekce?

Projekce seznamu automaticky přeskakuje prvky, které se vyhodnotí jako null, takže výsledek může být kratší než původní seznam. Vícenásobný hash klíč zachová a hodnotu null ponechá, což záleží při konstrukci odpovědí API.

Umí JMESPath agregaci a seskupování?

Umí základní agregaci pomocí sum(), max() a sort_by(). Seskupování, joins a window funkce jsou mimo standard. Složitou analýzu nechte na jq, SQL nebo kódu.

Jak se rozhodnout mezi JMESPath a JSONPath?

JSONPath použijte, když potřebujete vybrat uzly podle cesty a podmínky a dostat množinu uzlů; JMESPath použijte, když potřebujete výsledek přetvořit do podoby, kterou frontend očekává, s přejmenováním a ořezem polí. Když čtete jedno známé pole, nepoužívejte ani jedno; prostě přistupte k vlastnosti.

Mám použít pipe k získání první projektované hodnoty?

Ano. people[*].name je projekce, takže výsledkem je vždy seznam; bez pipe people[*].name[0] bere první znak každého jména. Pro první hodnotu napište people[*].name | [0].