Skip to content

Fast Erlang JSON data retrieval and updates via javascript-like notation

License

Notifications You must be signed in to change notification settings

GeneStevens/jsonpath

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JSONPath

JSONPath is an Erlang-based fast JSON data retrieval and update module. It operates on binary data and uses jiffy for fast and efficient decoding of binary JSON into structured Erlang terms and back again.

JSONPath is simple

For example, this simple JSON document:

{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}

Can be searched with JavaScript-like notation in binary:

(jsonpath@127.0.0.1)1> {ok, Data} = file:read_file("test.json").
{ok,<<"{\"menu\": {\n  \"id\": \"file\",\n  \"value\": \"File\",\n  \"popup\": {\n    \"menuitem\": [\n      {\"value\": \"New\", \"onclick"...>>}
(jsonpath@127.0.0.1)2> jsonpath:search(<<"menu.popup.menuitem[1].onclick">>, Data).
<<"OpenDoc()">>
(jsonpath@127.0.0.1)3>

JSONPath is fast

Using an 80KB Foursquare API venue search document to read a very specific node deep in the document can produce a result like so:

(jsonpath@127.0.0.1)4> jsonpath:search(<<"response.venues[6].categories[0].shortName">>, Data2).
<<"Sushi">>
(jsonpath@127.0.0.1)5>

Pre-decode the binary document into a structured Erlang term (via jiffy) and run that query one million times:

(jsonpath@127.0.0.1)3> JiffyData = jiffy:decode(Data2).
{[{<<"meta">>,{[{<<"code">>,200}]}},
  {<<"notifications">>,
   [{[{<<"item">>,{[{<<"unreadCount">>,2}]}},
      {<<"type">>,<<"notificationTray">>}]}]},
      ...
(jsonpath@127.0.0.1)4> jsonpath_tests:bench(jsonpath, search, [<<"response.venues[6].categories[0].shortName">>, JiffyData], 1000000).
Range: 0 - 8853 mics
Median: 5 mics
Average: 5 mics
5
(jsonpath@127.0.0.1)5>

That's 5 microseconds on average on a MacBook Pro.

JSONPath can alter your data

Using the same small JSON document from the first example, replace the content of a single node:

(jsonpath@127.0.0.1)9> Json = jsonpath:replace(<<"menu.popup.menuitem[1].onclick">>, <<"NewFunction()">>, Data).
{[{<<"menu">>,
   {[{<<"id">>,<<"file">>},
     {<<"value">>,<<"File">>},
     {<<"popup">>,
      {[{<<"menuitem">>,
         [{[{<<"value">>,<<"New">>},
            {<<"onclick">>,<<"CreateNewDoc()">>}]},
          {[{<<"value">>,<<"Open">>},
            {<<"onclick">>,<<"NewFunction()">>}]},
          {[{<<"value">>,<<"Close">>},
            {<<"onclick">>,<<"CloseDoc()">>}]}]}]}}]}}]}
(jsonpath@127.0.0.1)10> NewData = jiffy:encode(Json).
<<"{\"menu\":{\"id\":\"file\",\"value\":\"File\",\"popup\":{\"menuitem\":[{\"value\":\"New\",\"onclick\":\"CreateNewDoc()\"},{\"value\":\"Open\","...>>
(jsonpath@127.0.0.1)11> 

About

Fast Erlang JSON data retrieval and updates via javascript-like notation

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published