deepsearchjs
Search for key in deeply-nested objects.
Installation
$ yarn add deepsearchjs
Usage
search<T>(object: T, any> | Array<any>, searchTerm: string): P;
Name | Description | Required | Type |
---|---|---|---|
object |
Object to be searched | True | T = Record<any, any> | Array<any> |
searchTerm |
string to search for, a function that determines if an object key matches the query, or a regular expression to use for matching | True |
string or ((key: string, value: any) => boolean) or RegExp
|
output | Output object | --- |
P = Record<key: string, any> Where, key is a valid object path(eg. a.b.c[0].d.e , etc..)
|
Parameters
-
obj
(T
): The object to search. It is also generic, meaning it can accept any type of object. -
query
(string
|((key: string, value: any) => boolean)
|RegExp
): The query to search for. This can be a string, a function, or a regular expression.- If it is a string, the function will search for keys that end with that string.
- If it is a function, it will determine if the key matches the query.
- If it is a regular expression, it will test the key against that regular
Example
sample data
{ "users": [ { "id": 39101, "name": "Edwin Reichel", "email": "Kirk.Bednar@yahoo.com", "address": { "street": "1709 Carole Branch", "city": "Jenkinsboro", "state": "TX", "zip": "61317-0976", "phoneNumbers": [ { "type": "work", "number": "232.844.3064 x29733" }, { "type": "work", "number": "950.846.8118 x9126" } ], "previousAddresses": [ { "street": "82002 Connelly Dale", "city": "Folsom", "state": "MS", "zip": "20367-6986", "yearsLived": 10, "phoneNumbers": [{ "type": "work", "number": "1-997-352-5842" }], "previousAddresses": [ { "street": "663 Emie Way", "city": "Gradyton", "state": "OH", "zip": "09828-8254", "yearsLived": 5 }, { "street": "1991 Consuelo Roads", "city": "Gusbury", "state": "KY", "zip": "69719", "yearsLived": 1 } ] } ] }, "orders": [ { "id": 15686, "date": "Sun Jan 22 2023 15:36:15 GMT-0500 (Eastern Standard Time)", "total": 83285, "items": [ { "name": "Incredible Metal Shoes", "quantity": 1, "price": "469.00" }, { "name": "Unbranded Concrete Chair", "quantity": 6, "price": "999.00" }, { "name": "Licensed Concrete Sausages", "quantity": 9, "price": "657.00" }, { "name": "Electronic Rubber Ball", "quantity": 7, "price": "117.00" } ], "shippingAddress": { "street": "034 Wiza Forge", "city": "Glenniemouth", "state": "VT", "zip": "60082-4617" } } ] }, { "id": 41973, "name": "Melanie Upton", "email": "Alisha.Boyle@yahoo.com", "address": { "street": "69147 Bode Junctions", "city": "Bakersfield", "state": "WA", "zip": "83859", "phoneNumbers": [ { "type": "home", "number": "(263) 786-2737 x719" }, { "type": "home", "number": "1-536-445-2960" } ], "previousAddresses": [ { "street": "99456 Elliott Corner", "city": "Joanneburgh", "state": "ME", "zip": "41321", "yearsLived": 9, "phoneNumbers": [ { "type": "work", "number": "(999) 243-1101" }, { "type": "work", "number": "353.548.4339 x89335" } ], "previousAddresses": [ { "street": "591 Thomas Way", "city": "New Richmond", "state": "OH", "zip": "19873", "yearsLived": 3 }, { "street": "215 Shanahan Crescent", "city": "South Clarissa", "state": "MS", "zip": "31746", "yearsLived": 2 } ] } ] }, "orders": [ { "id": 21059, "date": "Sun Jan 22 2023 11:09:50 GMT-0500 (Eastern Standard Time)", "total": 38281, "items": [ { "name": "Rustic Frozen Shirt", "quantity": 3, "price": "797.00" }, { "name": "Luxurious Fresh Salad", "quantity": 3, "price": "290.00" }, { "name": "Ergonomic Bronze Pizza", "quantity": 10, "price": "380.00" } ], "shippingAddress": { "street": "35692 Miller Locks", "city": "Bowie", "state": "TN", "zip": "40565-6785" } } ] } ] }
index.ts
import { search } from "deepsearchjs";
import data from "./data.json";
// string as query
search(data, "city");
// call back function as query
search(data, (key: string, value: string): boolean => /city/gi.test(key));
// regex as query
search(data, /city/gi);
/*
* All three calls will have the same output:
* {
* "users[0].address.city": "Jenkinsboro",
* "users[0].address.previousAddresses[0].city": "Folsom",
* ...
* }
*/
TODO
- [ ] ci/cd: Automate versioning and releases
- [ ] feat: Optimize search algorithm to handle oversized datasets
- [ ] feat: Add a third parameter to the function to customize the search parameters ( leaf-node results only, etc... )
- [ ] feat: Search across values??
Benchmark
- text-based search x 22,188 ops/sec ±0.20% (94 runs sampled)
- regex-based search x 29,531 ops/sec ±0.11% (97 runs sampled)
- cb-based search x 9,243 ops/sec ±0.21% (96 runs sampled)
-
Fastest method ( for the current release ): regex-based search
✨ 🎉 !!
JSON results
{ "0": { "name": "text-based search", "options": { "async": false, "defer": false, "delay": 0.005, "initCount": 1, "maxTime": 5, "minSamples": 5, "minTime": 0.05 }, "async": false, "defer": false, "delay": 0.005, "initCount": 1, "maxTime": 5, "minSamples": 5, "minTime": 0.05, "id": 1, "stats": { "moe": 8.919914193248393e-8, "rme": 0.19791560818938855, "sem": 4.550976629208364e-8, "deviation": 4.41233554739717e-7, "mean": 0.00004506928116913744, "sample": [ 0.00004740194056603773, 0.0000460364371040724, 0.00004556789189189189, 0.00004596573333333333, 0.000046173843243243244, 0.00004558218409294013, 0.000045654660411081324, 0.000045964761394101876, 0.00004693349240393209, 0.00004503445755138516, 0.000045166541554959786, 0.000045024270777479894, 0.00004512364521894549, 0.00004538307911111111, 0.000044814896, 0.00004474414044444444, 0.000045182277333333336, 0.00004498920888888889, 0.000044812496, 0.00004502405422222222, 0.00004496076444444444, 0.00004460404977777778, 0.00004500752, 0.00004494280888888889, 0.00004513818844444444, 0.00004491765333333333, 0.00004500707644444444, 0.00004498112, 0.000045015164444444446, 0.00004517347733333334, 0.00004457160533333333, 0.00004508183288888889, 0.000045269922666666665, 0.000044854363555555555, 0.00004480645244444445, 0.00004480796355555556, 0.00004486671911111111, 0.000044939964444444443, 0.00004475667377777778, 0.00004533212223206377, 0.00004518623914968999, 0.00004478118689105403, 0.00004500625509300265, 0.00004517614171833481, 0.000044948947741364036, 0.00004509739858281665, 0.000044856298494242695, 0.00004497702568644819, 0.00004441758724534987, 0.00004486223294951284, 0.00004490722852081488, 0.000044977379982285206, 0.00004477277147918512, 0.00004486117006200177, 0.00004502396988485385, 0.00004529926129317981, 0.00004499908060230292, 0.0000449053684676705, 0.00004440447829937998, 0.00004522361824623561, 0.0000448341550044287, 0.00004499474047829938, 0.00004493991231178034, 0.000044967548272807795, 0.00004497667050487157, 0.000044914048715677594, 0.000044784552701505755, 0.00004500297785651019, 0.00004436435341009743, 0.00004498154295837024, 0.000044857271922054915, 0.00004496285296722763, 0.00004494531620903454, 0.00004523442338352525, 0.00004481706023029229, 0.000045150898139946854, 0.00004491475730735164, 0.000045246292294065545, 0.000045173065486725664, 0.00004490589557522124, 0.000045044037168141595, 0.00004502394955752212, 0.00004513182654867257, 0.000044929169911504425, 0.000044913505309734514, 0.00004496757699115044, 0.00004531306637168142, 0.000044335624778761064, 0.00004513589557522124, 0.00004492527256637168, 0.00004505005309734513, 0.000044830228318584074, 0.00004485368053097345, 0.00004479111238938053 ], "variance": 1.9468704982824687e-13 }, "times": { "cycle": 0.05092828772112531, "elapsed": 5.626, "period": 0.00004506928116913744, "timeStamp": 1680717841253 }, "running": false, "count": 1130, "cycles": 6, "hz": 22188.061891805373 }, "1": { "name": "regex-based search", "options": { "async": false, "defer": false, "delay": 0.005, "initCount": 1, "maxTime": 5, "minSamples": 5, "minTime": 0.05 }, "async": false, "defer": false, "delay": 0.005, "initCount": 1, "maxTime": 5, "minSamples": 5, "minTime": 0.05, "id": 2, "stats": { "moe": 3.6894965951722354e-8, "rme": 0.10895600391563913, "sem": 1.882396222026651e-8, "deviation": 1.8539452717378692e-7, "mean": 0.000033862260569219164, "sample": [ 0.00003389708327736736, 0.000034042752182672935, 0.00003373610073875084, 0.00003381689388851578, 0.00003377941907320349, 0.000033883717931497645, 0.00003400346406984553, 0.00003378207506702413, 0.00003450708109919571, 0.00003389722386058981, 0.00003381954155495979, 0.00003352141554959786, 0.00003381317426273458, 0.000033892531501340485, 0.00003413898123324397, 0.00003395452949061662, 0.00003364856166219839, 0.000033900507372654155, 0.00003401424798927614, 0.000033558547587131366, 0.000033853656836461126, 0.000033597153485254695, 0.000033723294235924934, 0.00003394695509383378, 0.000033862705764075066, 0.000033883349195710454, 0.000033816392091152815, 0.00003394253217158177, 0.0000340717553619303, 0.00003363622855227882, 0.00003371330764075067, 0.000033805533512064346, 0.000033768335120643434, 0.00003379246380697051, 0.00003369433914209115, 0.000033846552278820374, 0.000033780197721179624, 0.00003415215070328198, 0.00003365763831212324, 0.00003402616141995981, 0.0000339657461486939, 0.00003355355123911587, 0.00003379039249832552, 0.00003395255123911587, 0.00003361356597454789, 0.000033934265237776286, 0.000033801243134628266, 0.000033927231748158074, 0.00003420010850636303, 0.000033588782987273946, 0.00003385743938379102, 0.000033647122572002676, 0.000034104461486939047, 0.00003407920964501004, 0.0000336707669122572, 0.000033890460817146685, 0.00003399936972538513, 0.00003371075418620228, 0.000033928304085733425, 0.000033594007367716006, 0.00003391939584728734, 0.00003409662424648359, 0.000033651476892163434, 0.00003402421902210315, 0.00003373051239115874, 0.00003384216811788346, 0.00003399407836570663, 0.00003366078700602813, 0.00003384417749497656, 0.000033961928332217016, 0.00003365442330877428, 0.00003384926791694575, 0.00003373446416610851, 0.000033980414601473545, 0.00003427043737441393, 0.00003388222170127261, 0.00003411229738780978, 0.00003429475083724045, 0.00003385328667113195, 0.00003403828533154722, 0.00003373419624916276, 0.000033842636972538516, 0.0000340761955793704, 0.000033660585398526454, 0.00003390941527126591, 0.000033541428667113195, 0.00003389843134628265, 0.00003393540388479571, 0.00003374183255190891, 0.000034200040857334224, 0.00003408148693904889, 0.000033729038847957134, 0.00003392328064300067, 0.000033528300066979234, 0.00003394980509042197, 0.0000338437086403215, 0.000033660384460817145 ], "variance": 3.4371130705992015e-14 }, "times": { "cycle": 0.050556355029844215, "elapsed": 5.323, "period": 0.000033862260569219164, "timeStamp": 1680717846880 }, "running": false, "count": 1493, "cycles": 3, "hz": 29531.401128872098 }, "2": { "name": "cb-based search", "options": { "async": false, "defer": false, "delay": 0.005, "initCount": 1, "maxTime": 5, "minSamples": 5, "minTime": 0.05 }, "async": false, "defer": false, "delay": 0.005, "initCount": 1, "maxTime": 5, "minSamples": 5, "minTime": 0.05, "id": 3, "stats": { "moe": 2.2832766659322848e-7, "rme": 0.2110457577316177, "sem": 1.1649370744552474e-7, "deviation": 0.0000011414005659463887, "mean": 0.00010818870232093829, "sample": [ 0.0001095670129032258, 0.00010924958924731183, 0.00010938227956989247, 0.00010932738412017167, 0.00010893596351931331, 0.00011374931115879828, 0.00011221045708154507, 0.00010854341151385926, 0.00010878477825159915, 0.00010813104264392325, 0.00010845961620469083, 0.00010856183191489363, 0.00010823097872340425, 0.00010867332340425533, 0.00010652968510638298, 0.00010690990212765958, 0.00010819714893617022, 0.00010832842765957446, 0.00011286634042553191, 0.00010842885319148937, 0.00010660096382978722, 0.00010826821276595744, 0.00010810799787234042, 0.00010871651489361701, 0.00010823119148936171, 0.00010664330425531916, 0.0001083243829787234, 0.00010947673404255319, 0.0001084958744680851, 0.00010812310638297873, 0.00010668096382978722, 0.00010835864042553191, 0.0001078856574468085, 0.00010793778510638298, 0.00010798672127659575, 0.00010686458510638298, 0.00010842438510638297, 0.00010840991489361701, 0.00010839693617021277, 0.00010850757872340425, 0.00010685584680851063, 0.00010831564042553191, 0.00010851500638297873, 0.00010829713191489361, 0.00010838351489361702, 0.0001066707340425532, 0.00010795755531914894, 0.00010877160425531914, 0.00010829032127659575, 0.00010801734255319148, 0.00010641711489361702, 0.00010831351489361703, 0.00010853521914893617, 0.0001082524510638298, 0.00010815393829787233, 0.00010688435319148936, 0.00010835330212765957, 0.00010821968510638298, 0.00010849883617021277, 0.00010846351702127659, 0.00010666413829787235, 0.00010827755744680851, 0.00010839542978723404, 0.00010853607021276596, 0.00010802308723404255, 0.00010645434893617021, 0.00010806500212765958, 0.00010815819574468084, 0.00010835181276595745, 0.00010804798085106384, 0.00010664647872340426, 0.00010817415106382979, 0.0001081464914893617, 0.00010817308936170213, 0.00010815202340425532, 0.00010661626595744682, 0.00010833053617021276, 0.00010815564042553191, 0.0001080201085106383, 0.0001084775574468085, 0.0001065883914893617, 0.00010799564042553193, 0.00010837053617021277, 0.00010821670638297872, 0.00010797925744680852, 0.00010647392340425532, 0.00010849032553191489, 0.00010829883404255319, 0.00010789478723404256, 0.00010812755531914894, 0.00010644328510638298, 0.00010821287659574468, 0.00010834840851063831, 0.00010821308936170212, 0.00010823989787234042, 0.00010668052340425532 ], "variance": 1.3027952519427362e-12 }, "times": { "cycle": 0.050848690090840996, "elapsed": 5.393, "period": 0.00010818870232093829, "timeStamp": 1680717852203 }, "running": false, "count": 470, "cycles": 4, "hz": 9243.109294661213 }, "options": {}, "length": 3, "events": { "cycle": [ null ], "complete": [ null ] }, "running": false }