GeneStevens Jsonpath Save

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

Project README

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:

([email protected])1> {ok, Data} = file:read_file("test.json").
{ok,<<"{\"menu\": {\n  \"id\": \"file\",\n  \"value\": \"File\",\n  \"popup\": {\n    \"menuitem\": [\n      {\"value\": \"New\", \"onclick"...>>}
([email protected])2> jsonpath:search(<<"menu.popup.menuitem[1].onclick">>, Data).
<<"OpenDoc()">>
([email protected])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:

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

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

([email protected])3> JiffyData = jiffy:decode(Data2).
{[{<<"meta">>,{[{<<"code">>,200}]}},
  {<<"notifications">>,
   [{[{<<"item">>,{[{<<"unreadCount">>,2}]}},
      {<<"type">>,<<"notificationTray">>}]}]},
      ...
([email protected])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
([email protected])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:

([email protected])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()">>}]}]}]}}]}}]}
([email protected])10> NewData = jiffy:encode(Json).
<<"{\"menu\":{\"id\":\"file\",\"value\":\"File\",\"popup\":{\"menuitem\":[{\"value\":\"New\",\"onclick\":\"CreateNewDoc()\"},{\"value\":\"Open\","...>>
([email protected])11> 
Open Source Agenda is not affiliated with "GeneStevens Jsonpath" Project. README Source: GeneStevens/jsonpath
Stars
37
Open Issues
1
Last Commit
1 year ago
License

Open Source Agenda Badge

Open Source Agenda Rating