alkemis jsonQuery v.3 | jQuery plugin | there also is a non jQuery version

Code: jq_jsonQuery.js

jsonQuery is small javascript utility that searches json, with a call that is intuitive, concise, yet powerful.
Ease of use probably makes this function not as fast as a couple lines of a custom written search,
but the extra milliseconds of processing are insignificant unless you're dealing with a huge amount of data.
Compactness of this code should make it gain some speed points.
In fact, jsonQuery is its closer to a low-level JS function than a framework.
Written to work with browser memory but would be interesting to see how it would do with Local Storage or non-browsers.

other json queriers:
JsonPath has a js version, interaction is xPath-like
jaql not js at all, interaction is closer to SQL
JSONiq don't know much about this


jsonQ lives in jQuery's namespace as "jQuery.jsonQ" aka "$.jsonQ" FUNCTIONS: (3) $.jsonQ.find(params) //the main function params: source_json: object, //only required parameter items: string or array-of-strings or empty, query: string or array-of-strings or function or empty, sort: string or array-of-strings or function, item_delimiter_str: string, result_pathkeys_flag: boolean, log_queryerrors_flag: boolean more param info source_json (data object) items (string or array-of-strings) - if empty, any item - ".bicycle" - simple key - ".store.bicycle" - parent.child - ".building.*" - wildcard "*" - ".books.*" - wildcard "*" always needed for array items - ".business..bicycle" - ancestor-descendant ".." query (string or array-of-strings or function) - if empty, filters away nothing - if string/s, the string is a javascript expression, eg. '"Jane"' - as a convenience, if starts with dot and 'v' is left out, 'v' will be automatically prepended, eg. '.name=="Jane"' - if multiple, the logic will be "AND" (use callback function for AND, OR or any more complex logic) - as function, passes back 3 values (v, key, path_str) and if successful match, expects a js 'true' to be returned - since its a function, you can pretty much do anything, even mod the data sort (string or array-of-strings or function) - if empty, no sort - if string/s, the string is .key+direction, eg. greatest.. ".name>" or least.. ".name<" - as a convenience, if direction omitted, automatically treated as greatest, eg. ".name" - if multiple, will be primary, secondary, etc... - as function, is standard js sort function, passes back 2 values (a, b) and expects -1 or 1 (or 0) to be returned item_delimiter_str (string, most likely 1 char): - only affects your 'items' input and .path in the results - for edge cases like if your json uses "." in its keys, use a delimiter like "|" instead or perhaps you just prefer "/" over "." - item_delimiter_str is per call, the setting default_item_delimiter_str is persistent - also, see setting: default_item_delimiter_str: result_pathkeys_flag {boolean) - setting this flag will make result objects include .pathkeys log_queryerrors_flag log query errors (boolean) - by default, runtime errors in query are suppressed, (yes, we usually want that), how else do you get away with a line like: return v.title.indexOf("of the")>0;" - setting log_queryerrors_flag will console.warn those errors examples $.jsonQ.find({ source_json: js_obj, query: "v.price==22.99" }); $.jsonQ.find({source_json:js_obj, query:"v==20"}); //one liner $.jsonQ.find({ source_json: js_obj, items: ".books.*", //needs .* because we dont want the whole 'books' array, rather an item in that array query: [".price>10", ".isbn"] // && }); $.jsonQ.find({ source_json: js_obj, items: ".books.*", query: function(obj, key) { //a custom function, dont have to use name 'v', chose to use name 'obj' if (obj.price>10 || key>1) return 1; } }); //more examples (including sorting) in the source code of this page, commented out, look for "TESTS" return object .results (array of result objects) - always exists, even if empty: [] result object: .data (object ref) if data is object, its not a copy, its a pointer to the orig data object ie. if you modify values in the results objects, if you mean to or not, you are actually modifying the original json .path (string) these paths are correct as of the time of the search if you start modifying the json obj, especially deleting things, these paths can become incorrect ie. if you delete the item '[1]', another item in that array, with path '[8]' is no longer correct, '8' should be '7' json allows keys to pretty much be be any string - so if your keys have square brackets or a period in them (bad idea anyway) dont except the paths to be correct .pathkeys (array of keys, key can be string or number) example: ["business", "building", "store" ,"books", 2] this has to turned on with the single-object-argument version of the call, param: result_pathkeys_flag .error (string) - only if there was a fatal error .generated_query (string) - only if string/s was passed in as 'query' .generated_sort (string) - only if string/s was passed in as 'sort' $.jsonQ.pathkeys(str) //little data conversion function - pass it a string like: "[2]" //like a result_obj.path - get back an array like: ["business", "building", "store" ,"books", 2] $.jsonQ.set{setting_object) //a 'set settings' function only 1 settable setting: - default_item_delimiter_str //default is "." example: $.jsonQ.set({default_item_delimiter_str:":"}); //change to ":"
interactive tester:
json: (paste then 'parse json' OR use samples: 1 2 3 )

(all sample input uses sample json 1 for data)
sample items input

.bicycle - can be shortened to bicycle .books.* [".books.*", ".bicycle"] //multiples are "OR" sample query input
v.price - can be shortened to .price - but NOT "price""Herman Melville" [".price>10", ".category=='fiction'"] //multiples are "AND" v.color=="red" v.title.indexOf("of the")>0 function(v) {
if (v.title.indexOf("of the")>0 || v.price<10) return 1;
sample sort input
.price> - can be shortened to .price - or even price .price<

(string, for multiple strings, write like a js array)

multiple items act like "OR"

query: (string or function, for multiple strings, write like a js array)

multiple items act like "AND"

sort: (string or function, for multiple strings, write like a js array)