diff --git a/doctests/README.md b/doctests/README.md new file mode 100644 index 00000000000..59d1cb0364c --- /dev/null +++ b/doctests/README.md @@ -0,0 +1,32 @@ +# Command examples for redis.io + +## Setup + +To set up the examples folder so that you can run an example / develop one of your own: + +``` +$ git clone https://github.com/redis/node-redis.git +$ cd node-redis +$ npm install -ws && npm run build +$ cd doctests +$ npm install +``` + +## How to add examples + +Create regular node file in the current folder with meaningful name. It makes sense prefix example files with +command category (e.g. string, set, list, hash, etc) to make navigation in the folder easier. + +### Special markup + +See https://github.com/redis-stack/redis-stack-website#readme for more details. + +## How to test the examples + +Just include necessary assertions in the example file and run +```bash +sh doctests/run_examples.sh +``` +to test all examples in the current folder. + +See `tests.js` for more details. diff --git a/doctests/cmds-cnxmgmt.js b/doctests/cmds-cnxmgmt.js new file mode 100644 index 00000000000..2f4fc8dc95a --- /dev/null +++ b/doctests/cmds-cnxmgmt.js @@ -0,0 +1,49 @@ +// EXAMPLE: cmds_cnxmgmt +// REMOVE_START +import assert from "node:assert"; +// REMOVE_END + +// HIDE_START +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect().catch(console.error); +// HIDE_END + +// STEP_START auth1 +// REMOVE_START +await client.sendCommand(['CONFIG', 'SET', 'requirepass', 'temp_pass']); +// REMOVE_END +const res1 = await client.auth({ password: 'temp_pass' }); +console.log(res1); // OK + +const res2 = await client.auth({ username: 'default', password: 'temp_pass' }); +console.log(res2); // OK + +// REMOVE_START +assert.equal(res1, "OK"); +assert.equal(res2, "OK"); +await client.sendCommand(['CONFIG', 'SET', 'requirepass', '']); +// REMOVE_END +// STEP_END + +// STEP_START auth2 +// REMOVE_START +await client.sendCommand([ + 'ACL', 'SETUSER', 'test-user', + 'on', '>strong_password', '+acl' +]); +// REMOVE_END +const res3 = await client.auth({ username: 'test-user', password: 'strong_password' }); +console.log(res3); // OK + +// REMOVE_START +assert.equal(res3, "OK"); +await client.auth({ username: 'default', password: '' }) +await client.sendCommand(['ACL', 'DELUSER', 'test-user']); +// REMOVE_END +// STEP_END + +// HIDE_START +await client.quit(); +// HIDE_END diff --git a/doctests/cmds-generic.js b/doctests/cmds-generic.js new file mode 100644 index 00000000000..351b5a24d26 --- /dev/null +++ b/doctests/cmds-generic.js @@ -0,0 +1,195 @@ +// EXAMPLE: cmds_generic +// REMOVE_START +import assert from "node:assert"; +// REMOVE_END + +// HIDE_START +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect().catch(console.error); +// HIDE_END + +// STEP_START del +const delRes1 = await client.set('key1', 'Hello'); +console.log(delRes1); // OK + +const delRes2 = await client.set('key2', 'World'); +console.log(delRes2); // OK + +const delRes3 = await client.del(['key1', 'key2', 'key3']); +console.log(delRes3); // 2 +// REMOVE_START +assert.equal(delRes3, 2); +// REMOVE_END +// STEP_END + +// STEP_START expire +const expireRes1 = await client.set('mykey', 'Hello'); +console.log(expireRes1); // OK + +const expireRes2 = await client.expire('mykey', 10); +console.log(expireRes2); // 1 + +const expireRes3 = await client.ttl('mykey'); +console.log(expireRes3); // 10 +// REMOVE_START +assert.equal(expireRes3, 10); +// REMOVE_END + +const expireRes4 = await client.set('mykey', 'Hello World'); +console.log(expireRes4); // OK + +const expireRes5 = await client.ttl('mykey'); +console.log(expireRes5); // -1 +// REMOVE_START +assert.equal(expireRes5, -1); +// REMOVE_END + +const expireRes6 = await client.expire('mykey', 10, "XX"); +console.log(expireRes6); // 0 +// REMOVE_START +assert.equal(expireRes6, 0) +// REMOVE_END + +const expireRes7 = await client.ttl('mykey'); +console.log(expireRes7); // -1 +// REMOVE_START +assert.equal(expireRes7, -1); +// REMOVE_END + +const expireRes8 = await client.expire('mykey', 10, "NX"); +console.log(expireRes8); // 1 +// REMOVE_START +assert.equal(expireRes8, 1); +// REMOVE_END + +const expireRes9 = await client.ttl('mykey'); +console.log(expireRes9); // 10 +// REMOVE_START +assert.equal(expireRes9, 10); +await client.del('mykey'); +// REMOVE_END +// STEP_END + +// STEP_START ttl +const ttlRes1 = await client.set('mykey', 'Hello'); +console.log(ttlRes1); // OK + +const ttlRes2 = await client.expire('mykey', 10); +console.log(ttlRes2); // 1 + +const ttlRes3 = await client.ttl('mykey'); +console.log(ttlRes3); // 10 +// REMOVE_START +assert.equal(ttlRes3, 10); +await client.del('mykey'); +// REMOVE_END +// STEP_END + +// STEP_START scan1 +const scan1Res1 = await client.sAdd('myset', ['1', '2', '3', 'foo', 'foobar', 'feelsgood']); +console.log(scan1Res1); // 6 + +let scan1Res2 = []; +for await (const value of client.sScanIterator('myset', { MATCH: 'f*' })) { + scan1Res2 = scan1Res2.concat(value); +} +console.log(scan1Res2); // ['foo', 'foobar', 'feelsgood'] +// REMOVE_START +console.assert(scan1Res2.sort().toString() === ['foo', 'foobar', 'feelsgood'].sort().toString()); +await client.del('myset'); +// REMOVE_END +// STEP_END + +// STEP_START scan2 +// REMOVE_START +for (let i = 1; i <= 1000; i++) { + await client.set(`key:${i}`, i); +} +// REMOVE_END +let cursor = '0'; +let scanResult; + +scanResult = await client.scan(cursor, { MATCH: '*11*' }); +console.log(scanResult.cursor, scanResult.keys); + +scanResult = await client.scan(scanResult.cursor, { MATCH: '*11*' }); +console.log(scanResult.cursor, scanResult.keys); + +scanResult = await client.scan(scanResult.cursor, { MATCH: '*11*' }); +console.log(scanResult.cursor, scanResult.keys); + +scanResult = await client.scan(scanResult.cursor, { MATCH: '*11*' }); +console.log(scanResult.cursor, scanResult.keys); + +scanResult = await client.scan(scanResult.cursor, { MATCH: '*11*', COUNT: 1000 }); +console.log(scanResult.cursor, scanResult.keys); +// REMOVE_START +console.assert(scanResult.keys.length === 18); +cursor = '0'; +const prefix = 'key:*'; +while (cursor !== '0') { + scanResult = await client.scan(cursor, { MATCH: prefix, COUNT: 1000 }); + console.log(scanResult.cursor, scanResult.keys); + cursor = scanResult.cursor; + const keys = scanResult.keys; + if (keys.length) { + await client.del(keys); + } +} +// REMOVE_END +// STEP_END + +// STEP_START scan3 +const scan3Res1 = await client.geoAdd('geokey', { longitude: 0, latitude: 0, member: 'value' }); +console.log(scan3Res1); // 1 + +const scan3Res2 = await client.zAdd('zkey', [{ score: 1000, value: 'value' }]); +console.log(scan3Res2); // 1 + +const scan3Res3 = await client.type('geokey'); +console.log(scan3Res3); // zset +// REMOVE_START +console.assert(scan3Res3 === 'zset'); +// REMOVE_END + +const scan3Res4 = await client.type('zkey'); +console.log(scan3Res4); // zset +// REMOVE_START +console.assert(scan3Res4 === 'zset'); +// REMOVE_END + +const scan3Res5 = await client.scan('0', { TYPE: 'zset' }); +console.log(scan3Res5.keys); // ['zkey', 'geokey'] +// REMOVE_START +console.assert(scan3Res5.keys.sort().toString() === ['zkey', 'geokey'].sort().toString()); +await client.del(['geokey', 'zkey']); +// REMOVE_END +// STEP_END + +// STEP_START scan4 +const scan4Res1 = await client.hSet('myhash', { a: 1, b: 2 }); +console.log(scan4Res1); // 2 + +const scan4Res2 = await client.hScan('myhash', 0); +console.log(scan4Res2.tuples); // [{field: 'a', value: '1'}, {field: 'b', value: '2'}] +// REMOVE_START +assert.deepEqual(scan4Res2.tuples, [ + { field: 'a', value: '1' }, + { field: 'b', value: '2' } +]); +// REMOVE_END + +const scan4Res3 = await client.hScan('myhash', 0, { COUNT: 10 }); +const items = scan4Res3.tuples.map((item) => item.field) +console.log(items); // ['a', 'b'] +// REMOVE_START +assert.deepEqual(items, ['a', 'b']) +await client.del('myhash'); +// REMOVE_END +// STEP_END + +// HIDE_START +await client.quit(); +// HIDE_END diff --git a/doctests/cmds-hash.js b/doctests/cmds-hash.js new file mode 100644 index 00000000000..8ce29785763 --- /dev/null +++ b/doctests/cmds-hash.js @@ -0,0 +1,109 @@ +// EXAMPLE: cmds_hash +// HIDE_START +import assert from 'node:assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect().catch(console.error); +// HIDE_END + +// STEP_START hset +const res1 = await client.hSet('myhash', 'field1', 'Hello') +console.log(res1) // 1 + +const res2 = await client.hGet('myhash', 'field1') +console.log(res2) // Hello + +const res3 = await client.hSet( + 'myhash', + { + 'field2': 'Hi', + 'field3': 'World' + } +) +console.log(res3) // 2 + +const res4 = await client.hGet('myhash', 'field2') +console.log(res4) // Hi + +const res5 = await client.hGet('myhash', 'field3') +console.log(res5) // World + +const res6 = await client.hGetAll('myhash') +console.log(res6) + +// REMOVE_START +assert.equal(res1, 1); +assert.equal(res2, 'Hello'); +assert.equal(res3, 2); +assert.equal(res4, 'Hi'); +assert.equal(res5, 'World'); +assert.deepEqual(res6, { + field1: 'Hello', + field2: 'Hi', + field3: 'World' +}); +await client.del('myhash') +// REMOVE_END +// STEP_END + +// STEP_START hget +const res7 = await client.hSet('myhash', 'field1', 'foo') +console.log(res7) // 1 + +const res8 = await client.hGet('myhash', 'field1') +console.log(res8) // foo + +const res9 = await client.hGet('myhash', 'field2') +console.log(res9) // null + +// REMOVE_START +assert.equal(res7, 1); +assert.equal(res8, 'foo'); +assert.equal(res9, null); +await client.del('myhash') +// REMOVE_END +// STEP_END + +// STEP_START hgetall +const res10 = await client.hSet( + 'myhash', + { + 'field1': 'Hello', + 'field2': 'World' + } +) + +const res11 = await client.hGetAll('myhash') +console.log(res11) // [Object: null prototype] { field1: 'Hello', field2: 'World' } + +// REMOVE_START +assert.deepEqual(res11, { + field1: 'Hello', + field2: 'World' +}); +await client.del('myhash') +// REMOVE_END +// STEP_END + +// STEP_START hvals +const res12 = await client.hSet( + 'myhash', + { + 'field1': 'Hello', + 'field2': 'World' + } +) + +const res13 = await client.hVals('myhash') +console.log(res13) // [ 'Hello', 'World' ] + +// REMOVE_START +assert.deepEqual(res13, [ 'Hello', 'World' ]); +await client.del('myhash') +// REMOVE_END +// STEP_END + +// HIDE_START +await client.close(); +// HIDE_END diff --git a/doctests/cmds-list.js b/doctests/cmds-list.js new file mode 100644 index 00000000000..9d1b4154dfe --- /dev/null +++ b/doctests/cmds-list.js @@ -0,0 +1,129 @@ +// EXAMPLE: cmds_list +// HIDE_START +import assert from 'node:assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect().catch(console.error); +// HIDE_END + +// STEP_START lpush +const res1 = await client.lPush('mylist', 'world'); +console.log(res1); // 1 + +const res2 = await client.lPush('mylist', 'hello'); +console.log(res2); // 2 + +const res3 = await client.lRange('mylist', 0, -1); +console.log(res3); // [ 'hello', 'world' ] + +// REMOVE_START +assert.deepEqual(res3, [ 'hello', 'world' ]); +await client.del('mylist'); +// REMOVE_END +// STEP_END + +// STEP_START lrange +const res4 = await client.rPush('mylist', 'one'); +console.log(res4); // 1 + +const res5 = await client.rPush('mylist', 'two'); +console.log(res5); // 2 + +const res6 = await client.rPush('mylist', 'three'); +console.log(res6); // 3 + +const res7 = await client.lRange('mylist', 0, 0); +console.log(res7); // [ 'one' ] + +const res8 = await client.lRange('mylist', -3, 2); +console.log(res8); // [ 'one', 'two', 'three' ] + +const res9 = await client.lRange('mylist', -100, 100); +console.log(res9); // [ 'one', 'two', 'three' ] + +const res10 = await client.lRange('mylist', 5, 10); +console.log(res10); // [] + +// REMOVE_START +assert.deepEqual(res7, [ 'one' ]); +assert.deepEqual(res8, [ 'one', 'two', 'three' ]); +assert.deepEqual(res9, [ 'one', 'two', 'three' ]); +assert.deepEqual(res10, []); +await client.del('mylist'); +// REMOVE_END +// STEP_END + +// STEP_START llen +const res11 = await client.lPush('mylist', 'World'); +console.log(res11); // 1 + +const res12 = await client.lPush('mylist', 'Hello'); +console.log(res12); // 2 + +const res13 = await client.lLen('mylist'); +console.log(res13); // 2 + +// REMOVE_START +assert.equal(res13, 2); +await client.del('mylist'); +// REMOVE_END +// STEP_END + +// STEP_START rpush +const res14 = await client.rPush('mylist', 'hello'); +console.log(res14); // 1 + +const res15 = await client.rPush('mylist', 'world'); +console.log(res15); // 2 + +const res16 = await client.lRange('mylist', 0, -1); +console.log(res16); // [ 'hello', 'world' ] + +// REMOVE_START +assert.deepEqual(res16, [ 'hello', 'world' ]); +await client.del('mylist'); +// REMOVE_END +// STEP_END + +// STEP_START lpop +const res17 = await client.rPush('mylist', ["one", "two", "three", "four", "five"]); +console.log(res17); // 5 + +const res18 = await client.lPop('mylist'); +console.log(res18); // 'one' + +const res19 = await client.lPopCount('mylist', 2); +console.log(res19); // [ 'two', 'three' ] + +const res20 = await client.lRange('mylist', 0, -1); +console.log(res20); // [ 'four', 'five' ] + +// REMOVE_START +assert.deepEqual(res20, [ 'four', 'five' ]); +await client.del('mylist'); +// REMOVE_END +// STEP_END + +// STEP_START rpop +const res21 = await client.rPush('mylist', ["one", "two", "three", "four", "five"]); +console.log(res21); // 5 + +const res22 = await client.rPop('mylist'); +console.log(res22); // 'five' + +const res23 = await client.rPopCount('mylist', 2); +console.log(res23); // [ 'four', 'three' ] + +const res24 = await client.lRange('mylist', 0, -1); +console.log(res24); // [ 'one', 'two' ] + +// REMOVE_START +assert.deepEqual(res24, [ 'one', 'two' ]); +await client.del('mylist'); +// REMOVE_END +// STEP_END + +// HIDE_START +await client.close(); +// HIDE_END diff --git a/doctests/cmds-servermgmt.js b/doctests/cmds-servermgmt.js new file mode 100644 index 00000000000..0a53e05919d --- /dev/null +++ b/doctests/cmds-servermgmt.js @@ -0,0 +1,45 @@ +// EXAMPLE: cmds_servermgmt +// REMOVE_START +import assert from 'node:assert'; +// REMOVE_END + +// HIDE_START +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect().catch(console.error); +// HIDE_END + +// STEP_START flushall +// REMOVE_START +await client.set('foo', '1'); +await client.set('bar', '2'); +await client.set('baz', '3'); +// REMOVE_END +const res1 = await client.flushAll('SYNC'); // or ASYNC +console.log(res1); // OK + +const res2 = await client.keys('*'); +console.log(res2); // [] + +// REMOVE_START +assert.equal(res1, 'OK'); +assert.deepEqual(res2, []); +// REMOVE_END +// STEP_END + +// STEP_START info +const res3 = await client.info(); +console.log(res3) +// # Server +// redis_version:7.4.0 +// redis_git_sha1:c9d29f6a +// redis_git_dirty:0 +// redis_build_id:4c367a16e3f9616 +// redis_mode:standalone +// ... +// STEP_END + +// HIDE_START +await client.close(); +// HIDE_END diff --git a/doctests/cmds-set.js b/doctests/cmds-set.js new file mode 100644 index 00000000000..8a9a3837036 --- /dev/null +++ b/doctests/cmds-set.js @@ -0,0 +1,44 @@ +// EXAMPLE: cmds_set +// REMOVE_START +import assert from 'node:assert'; +// REMOVE_END + +// HIDE_START +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect().catch(console.error); +// HIDE_END + +// STEP_START sadd +const res1 = await client.sAdd('myset', ['Hello', 'World']); +console.log(res1); // 2 + +const res2 = await client.sAdd('myset', ['World']); +console.log(res2); // 0 + +const res3 = await client.sMembers('myset') +console.log(res3); // ['Hello', 'World'] + +// REMOVE_START +assert.deepEqual(res3, ['Hello', 'World']); +await client.del('myset'); +// REMOVE_END +// STEP_END + +// STEP_START smembers +const res4 = await client.sAdd('myset', ['Hello', 'World']); +console.log(res4); // 2 + +const res5 = await client.sMembers('myset') +console.log(res5); // ['Hello', 'World'] + +// REMOVE_START +assert.deepEqual(res5, ['Hello', 'World']); +await client.del('myset'); +// REMOVE_END +// STEP_END + +// HIDE_START +await client.close(); +// HIDE_END diff --git a/doctests/cmds-sorted-set.js b/doctests/cmds-sorted-set.js new file mode 100644 index 00000000000..b718938cc2b --- /dev/null +++ b/doctests/cmds-sorted-set.js @@ -0,0 +1,115 @@ +// EXAMPLE: cmds_sorted_set +// REMOVE_START +import assert from "node:assert"; +// REMOVE_END + +// HIDE_START +import { createClient } from 'redis'; + +const client = createClient(); +client.on('error', err => console.log('Redis Client Error', err)); +await client.connect().catch(console.error); +// HIDE_END + +// STEP_START zadd +const val1 = await client.zAdd("myzset", [{ value: 'one', score: 1 }]); +console.log(val1); +// returns 1 + +const val2 = await client.zAdd("myzset", [{ value: 'uno', score: 1 }]); +console.log(val2); +// returns 1 + +const val3 = await client.zAdd("myzset", [{ value: 'two', score: 2 }, { value: 'three', score: 3 }]); +console.log(val3); +// returns 2 + +const val4 = await client.zRangeWithScores("myzset", 0, -1); +console.log(val4); +// returns [{value: 'one', score: 1}, {value: 'uno', score: 1}, {value: 'two', score: 2}, {value: 'three', score: 3} ] + +// REMOVE_START +assert.equal(val1, 1); +assert.equal(val2, 1); +assert.equal(val3, 2); +assert.deepEqual(val4, [ + { value: 'one', score: 1 }, + { value: 'uno', score: 1 }, + { value: 'two', score: 2 }, + { value: 'three', score: 3 } +]); +await client.del('myzset'); +// REMOVE_END +// STEP_END + +// STEP_START zrange1 +const val5 = await client.zAdd("myzset", [ + { value: 'one', score: 1 }, + { value: 'two', score: 2 }, + { value: 'three', score: 3 } +]); +console.log(val5); +// returns 3 + +const val6 = await client.zRange('myzset', 0, -1); +console.log(val6); +// returns ['one', 'two', 'three'] +// REMOVE_START +console.assert(JSON.stringify(val6) === JSON.stringify(['one', 'two', 'three'])); +// REMOVE_END + +const val7 = await client.zRange('myzset', 2, 3); +console.log(val7); +// returns ['three'] +// REMOVE_START +console.assert(JSON.stringify(val7) === JSON.stringify(['three'])); +// REMOVE_END + +const val8 = await client.zRange('myzset', -2, -1); +console.log(val8); +// returns ['two', 'three'] +// REMOVE_START +console.assert(JSON.stringify(val8) === JSON.stringify(['two', 'three'])); +await client.del('myzset'); +// REMOVE_END +// STEP_END + +// STEP_START zrange2 +const val9 = await client.zAdd("myzset", [ + { value: 'one', score: 1 }, + { value: 'two', score: 2 }, + { value: 'three', score: 3 } +]); +console.log(val9); +// returns 3 + +const val10 = await client.zRangeWithScores('myzset', 0, 1); +console.log(val10); +// returns [{value: 'one', score: 1}, {value: 'two', score: 2}] +// REMOVE_START +console.assert(JSON.stringify(val10) === JSON.stringify([{value: 'one', score: 1}, {value: 'two', score: 2}])); +await client.del('myzset'); +// REMOVE_END +// STEP_END + +// STEP_START zrange3 +const val11 = await client.zAdd("myzset", [ + { value: 'one', score: 1 }, + { value: 'two', score: 2 }, + { value: 'three', score: 3 } +]); +console.log(val11); +// returns 3 + +const val12 = await client.zRange('myzset', 2, 3, { BY: 'SCORE', LIMIT: { offset: 1, count: 1 } }); +console.log(val12); +// >>> ['three'] +// REMOVE_START +console.assert(JSON.stringify(val12) === JSON.stringify(['three'])); +await client.del('myzset'); +// REMOVE_END +// STEP_END + +// HIDE_START +await client.close(); +// HIDE_END diff --git a/doctests/cmds-string.js b/doctests/cmds-string.js new file mode 100644 index 00000000000..00b3f738fa3 --- /dev/null +++ b/doctests/cmds-string.js @@ -0,0 +1,27 @@ +// EXAMPLE: cmds_string +// REMOVE_START +import assert from "node:assert"; +// REMOVE_END + +// HIDE_START +import { createClient } from 'redis'; + +const client = createClient(); +client.on('error', err => console.log('Redis Client Error', err)); +await client.connect().catch(console.error); +// HIDE_END + +// STEP_START incr +await client.set("mykey", "10"); +const value1 = await client.incr("mykey"); +console.log(value1); +// returns 11 +// REMOVE_START +assert.equal(value1, 11); +await client.del('mykey'); +// REMOVE_END +// STEP_END + +// HIDE_START +await client.close(); +// HIDE_END diff --git a/doctests/data/query_em.json b/doctests/data/query_em.json new file mode 100644 index 00000000000..bcf908aaf85 --- /dev/null +++ b/doctests/data/query_em.json @@ -0,0 +1,92 @@ +[ + { + "pickup_zone": "POLYGON((-74.0610 40.7578, -73.9510 40.7578, -73.9510 40.6678, -74.0610 40.6678, -74.0610 40.7578))", + "store_location": "-74.0060,40.7128", + "brand": "Velorim", + "model": "Jigger", + "price": 270, + "description": "Small and powerful, the Jigger is the best ride for the smallest of tikes! This is the tiniest kids’ pedal bike on the market available without a coaster brake, the Jigger is the vehicle of choice for the rare tenacious little rider raring to go.", + "condition": "new" + }, + { + "pickup_zone": "POLYGON((-118.2887 34.0972, -118.1987 34.0972, -118.1987 33.9872, -118.2887 33.9872, -118.2887 34.0972))", + "store_location": "-118.2437,34.0522", + "brand": "Bicyk", + "model": "Hillcraft", + "price": 1200, + "description": "Kids want to ride with as little weight as possible. Especially on an incline! They may be at the age when a 27.5\" wheel bike is just too clumsy coming off a 24\" bike. The Hillcraft 26 is just the solution they need!", + "condition": "used" + }, + { + "pickup_zone": "POLYGON((-87.6848 41.9331, -87.5748 41.9331, -87.5748 41.8231, -87.6848 41.8231, -87.6848 41.9331))", + "store_location": "-87.6298,41.8781", + "brand": "Nord", + "model": "Chook air 5", + "price": 815, + "description": "The Chook Air 5 gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. The lower top tube makes it easy to mount and dismount in any situation, giving your kids greater safety on the trails.", + "condition": "used" + }, + { + "pickup_zone": "POLYGON((-80.2433 25.8067, -80.1333 25.8067, -80.1333 25.6967, -80.2433 25.6967, -80.2433 25.8067))", + "store_location": "-80.1918,25.7617", + "brand": "Eva", + "model": "Eva 291", + "price": 3400, + "description": "The sister company to Nord, Eva launched in 2005 as the first and only women-dedicated bicycle brand. Designed by women for women, allEva bikes are optimized for the feminine physique using analytics from a body metrics database. If you like 29ers, try the Eva 291. It’s a brand new bike for 2022.. This full-suspension, cross-country ride has been designed for velocity. The 291 has 100mm of front and rear travel, a superlight aluminum frame and fast-rolling 29-inch wheels. Yippee!", + "condition": "used" + }, + { + "pickup_zone": "POLYGON((-122.4644 37.8199, -122.3544 37.8199, -122.3544 37.7099, -122.4644 37.7099, -122.4644 37.8199))", + "store_location": "-122.4194,37.7749", + "brand": "Noka Bikes", + "model": "Kahuna", + "price": 3200, + "description": "Whether you want to try your hand at XC racing or are looking for a lively trail bike that's just as inspiring on the climbs as it is over rougher ground, the Wilder is one heck of a bike built specifically for short women. Both the frames and components have been tweaked to include a women’s saddle, different bars and unique colourway.", + "condition": "used" + }, + { + "pickup_zone": "POLYGON((-0.1778 51.5524, 0.0822 51.5524, 0.0822 51.4024, -0.1778 51.4024, -0.1778 51.5524))", + "store_location": "-0.1278,51.5074", + "brand": "Breakout", + "model": "XBN 2.1 Alloy", + "price": 810, + "description": "The XBN 2.1 Alloy is our entry-level road bike – but that’s not to say that it’s a basic machine. With an internal weld aluminium frame, a full carbon fork, and the slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance.", + "condition": "new" + }, + { + "pickup_zone": "POLYGON((2.1767 48.9016, 2.5267 48.9016, 2.5267 48.5516, 2.1767 48.5516, 2.1767 48.9016))", + "store_location": "2.3522,48.8566", + "brand": "ScramBikes", + "model": "WattBike", + "price": 2300, + "description": "The WattBike is the best e-bike for people who still feel young at heart. It has a Bafang 1000W mid-drive system and a 48V 17.5AH Samsung Lithium-Ion battery, allowing you to ride for more than 60 miles on one charge. It’s great for tackling hilly terrain or if you just fancy a more leisurely ride. With three working modes, you can choose between E-bike, assisted bicycle, and normal bike modes.", + "condition": "new" + }, + { + "pickup_zone": "POLYGON((13.3260 52.5700, 13.6550 52.5700, 13.6550 52.2700, 13.3260 52.2700, 13.3260 52.5700))", + "store_location": "13.4050,52.5200", + "brand": "Peaknetic", + "model": "Secto", + "price": 430, + "description": "If you struggle with stiff fingers or a kinked neck or back after a few minutes on the road, this lightweight, aluminum bike alleviates those issues and allows you to enjoy the ride. From the ergonomic grips to the lumbar-supporting seat position, the Roll Low-Entry offers incredible comfort. The rear-inclined seat tube facilitates stability by allowing you to put a foot on the ground to balance at a stop, and the low step-over frame makes it accessible for all ability and mobility levels. The saddle is very soft, with a wide back to support your hip joints and a cutout in the center to redistribute that pressure. Rim brakes deliver satisfactory braking control, and the wide tires provide a smooth, stable ride on paved roads and gravel. Rack and fender mounts facilitate setting up the Roll Low-Entry as your preferred commuter, and the BMX-like handlebar offers space for mounting a flashlight, bell, or phone holder.", + "condition": "new" + }, + { + "pickup_zone": "POLYGON((1.9450 41.4301, 2.4018 41.4301, 2.4018 41.1987, 1.9450 41.1987, 1.9450 41.4301))", + "store_location": "2.1734, 41.3851", + "brand": "nHill", + "model": "Summit", + "price": 1200, + "description": "This budget mountain bike from nHill performs well both on bike paths and on the trail. The fork with 100mm of travel absorbs rough terrain. Fat Kenda Booster tires give you grip in corners and on wet trails. The Shimano Tourney drivetrain offered enough gears for finding a comfortable pace to ride uphill, and the Tektro hydraulic disc brakes break smoothly. Whether you want an affordable bike that you can take to work, but also take trail in mountains on the weekends or you’re just after a stable, comfortable ride for the bike path, the Summit gives a good value for money.", + "condition": "new" + }, + { + "pickup_zone": "POLYGON((12.4464 42.1028, 12.5464 42.1028, 12.5464 41.7028, 12.4464 41.7028, 12.4464 42.1028))", + "store_location": "12.4964,41.9028", + "model": "ThrillCycle", + "brand": "BikeShind", + "price": 815, + "description": "An artsy, retro-inspired bicycle that’s as functional as it is pretty: The ThrillCycle steel frame offers a smooth ride. A 9-speed drivetrain has enough gears for coasting in the city, but we wouldn’t suggest taking it to the mountains. Fenders protect you from mud, and a rear basket lets you transport groceries, flowers and books. The ThrillCycle comes with a limited lifetime warranty, so this little guy will last you long past graduation.", + "condition": "refurbished" + } +] diff --git a/doctests/data/query_vector.json b/doctests/data/query_vector.json new file mode 100644 index 00000000000..625479e111b --- /dev/null +++ b/doctests/data/query_vector.json @@ -0,0 +1,3952 @@ +[ + { + "brand": "Velorim", + "condition": "new", + "description": "Small and powerful, the Jigger is the best ride for the smallest of tikes! This is the tiniest kids\u2019 pedal bike on the market available without a coaster brake, the Jigger is the vehicle of choice for the rare tenacious little rider raring to go.", + "description_embeddings": [ + -0.026918452233076096, + 0.07200391590595245, + 0.019199736416339874, + -0.024749649688601494, + -0.09264523535966873, + 0.017702950164675713, + 0.11252444237470627, + 0.09377790987491608, + 0.005099582951515913, + 0.07054618746042252, + 0.0025260779075324535, + -0.04007257893681526, + 0.013598357327282429, + 0.03940897434949875, + -0.0069704861380159855, + 0.057934146374464035, + 0.15386416018009186, + 0.04337097704410553, + 0.07119690626859665, + -0.048173222690820694, + -0.09069827198982239, + -0.016886970028281212, + -0.04425429925322533, + -0.019464140757918358, + -0.027470778673887253, + 0.005336642265319824, + -0.09170512855052948, + 0.03556380048394203, + 0.023559197783470154, + -0.03628315031528473, + -0.04448218643665314, + 0.011364061385393143, + 0.009603296406567097, + -0.04861818626523018, + -0.03343017399311066, + -0.01483147218823433, + 0.06086479872465134, + 0.02109363302588463, + -0.025959225371479988, + 0.014000430703163147, + -0.00846729427576065, + 0.07305800914764404, + 0.02457829751074314, + -0.12663941085338593, + 0.010544337332248688, + 0.013315590098500252, + 0.07280771434307098, + -0.08232685923576355, + 0.0040486594662070274, + -0.026350753381848335, + 0.06408613175153732, + -0.01415738184005022, + 0.04628903791308403, + -0.02050374448299408, + 0.04177685081958771, + -0.09207800775766373, + -0.005421833600848913, + -0.005136478692293167, + -0.024564260616898537, + 0.026354163885116577, + -0.05851329490542412, + 0.03147275745868683, + -0.02183554694056511, + 0.03346295654773712, + -0.02240697667002678, + -0.09603817760944366, + -0.02274233102798462, + -0.039677977561950684, + 0.007695100735872984, + 0.039304088801145554, + -0.017668871209025383, + 0.022897064685821533, + -0.039273541420698166, + 0.08864572644233704, + -0.04432578384876251, + -0.06769558042287827, + 0.06696884334087372, + 0.07118263095617294, + -0.024863263592123985, + 0.01151553075760603, + -0.11591693758964539, + -0.025131937116384506, + 0.052269868552684784, + -0.03035089746117592, + 0.00906881783157587, + 0.04585501551628113, + 0.038361817598342896, + 0.03026638925075531, + 0.015340524725615978, + -0.006911538541316986, + 0.022395918145775795, + 0.13969141244888306, + 0.047686025500297546, + 0.05438247323036194, + 0.02779674343764782, + -0.04191797226667404, + -0.021741557866334915, + 0.003305602353066206, + -0.11100355535745621, + 0.016258426010608673, + 0.06977421790361404, + 0.08189859241247177, + 0.0966871827840805, + 0.03519754856824875, + 0.05674563720822334, + 0.034512776881456375, + 0.07052291929721832, + -0.06342307478189468, + 0.051868196576833725, + -0.013776403851807117, + -0.007541927974671125, + -0.043183840811252594, + 0.021481933072209358, + 0.0380198135972023, + -0.07870583236217499, + -0.10873759537935257, + -0.08491706103086472, + 0.03155837208032608, + -0.03790571913123131, + 0.041968367993831635, + -0.00593406381085515, + 0.036538854241371155, + -0.004705581348389387, + 0.004229994490742683, + -0.00729013979434967, + -0.019296232610940933, + -0.014331319369375706, + -4.401502220942261e-34, + -0.0067550260573625565, + 0.07402423769235611, + -0.012888211756944656, + -0.055266380310058594, + 0.04810081049799919, + 0.005175809375941753, + -0.004325157031416893, + -0.10392399877309799, + -0.03650582954287529, + 0.07477248460054398, + 0.0022102247457951307, + -0.05040738359093666, + -0.003033560933545232, + 0.060498371720314026, + 0.08619660884141922, + -0.04577762633562088, + -0.10468175262212753, + -0.07177772372961044, + -0.05756700038909912, + -0.02839704230427742, + -0.028650879859924316, + -0.010213681496679783, + 0.008074316196143627, + 0.03448071703314781, + -0.025478240102529526, + -0.029753824695944786, + 0.05397271364927292, + -0.0006062929751351476, + -0.03292117267847061, + 0.040799956768751144, + -0.0933983102440834, + -0.026921836659312248, + 0.00327915046364069, + -0.025635670870542526, + -0.057946983724832535, + -0.06664302200078964, + 0.04280361905694008, + -0.027111517265439034, + -0.08359260112047195, + 0.03483080118894577, + 0.023318039253354073, + -0.08598511666059494, + -0.08378149569034576, + 0.054067932069301605, + -0.014853178523480892, + -0.05498708039522171, + 0.0711284726858139, + 0.12539872527122498, + -0.04355800896883011, + -0.027553806081414223, + -0.009111037477850914, + -0.058482203632593155, + 0.07053986191749573, + -0.009027705527842045, + -0.017481567338109016, + 0.011404255405068398, + 0.06084389239549637, + -0.028110956773161888, + -0.08594057708978653, + 0.05215488001704216, + -0.07651112973690033, + -0.027076181024312973, + -0.01357623003423214, + -0.01263132132589817, + -0.0193876251578331, + 0.013576658442616463, + 0.038156066089868546, + -0.04309772700071335, + -0.04051121696829796, + -0.025885144248604774, + -0.003073574509471655, + -0.0003303807170595974, + 0.08043289929628372, + -0.039484549313783646, + 0.10091833025217056, + -0.04735022410750389, + 0.027813943102955818, + -0.0038837436586618423, + -0.05234759673476219, + -0.00716474698856473, + 0.016360750421881676, + -0.025806615129113197, + -0.03212691470980644, + -0.08456144481897354, + -0.019326699897646904, + -0.03228791803121567, + 0.07633069902658463, + -0.07643644511699677, + -0.03988131135702133, + 0.02396279387176037, + -0.055901359766721725, + 0.009231535717844963, + 0.0344320572912693, + 0.07486359030008316, + -0.03505600243806839, + -2.324423447670953e-34, + -0.04453577473759651, + 0.06512241810560226, + 0.03920532390475273, + 0.062222111970186234, + -0.015745285898447037, + -0.017774563282728195, + 0.08228200674057007, + -0.05798694118857384, + -0.042758435010910034, + -0.018822822719812393, + -0.07607664912939072, + -0.02666221559047699, + 0.036936040967702866, + -0.034714240580797195, + 0.06992944329977036, + 0.00530517753213644, + -0.0005260169273242354, + -0.03961028903722763, + 0.08799499273300171, + -0.04191635549068451, + 0.07468635588884354, + -0.010930310003459454, + -0.0611649826169014, + -0.04100184887647629, + 0.07131826132535934, + 0.03241356834769249, + -0.0545443594455719, + -0.005295638460665941, + -0.04712966829538345, + 0.032524388283491135, + -0.05130890756845474, + -0.01299980841577053, + 0.06523969769477844, + -0.011433755978941917, + 0.018730396404862404, + 0.047184932976961136, + -0.043041545897722244, + -0.03231072053313255, + -0.015864262357354164, + 0.03991076350212097, + -0.017617924138903618, + -0.03504975512623787, + 0.027346905320882797, + 0.05564267560839653, + 0.01610865257680416, + 0.0470576174557209, + -0.010647954419255257, + 0.13047614693641663, + -0.011055804789066315, + 0.011903814040124416, + -0.01350466813892126, + -0.0019897734746336937, + 0.053073540329933167, + 0.0717632919549942, + 0.007322370074689388, + -0.0206251572817564, + 0.061210062354803085, + 0.03184640407562256, + -0.035093698650598526, + -0.0026315131690353155, + -0.03291690722107887, + -0.04229205846786499, + -0.04241437837481499, + 0.1091129332780838, + 0.02229561097919941, + 0.02223002351820469, + 0.03949614241719246, + 0.031568314880132675, + -0.07121116667985916, + -0.07664268463850021, + -0.04235681891441345, + -0.011173299513757229, + 0.1190338209271431, + -0.09825095534324646, + -0.0375107042491436, + 0.007167852018028498, + 0.047537703067064285, + 0.044423725455999374, + 0.022106878459453583, + -0.02811007760465145, + 0.033864255994558334, + 0.0643145889043808, + 0.03725901246070862, + -0.0497952364385128, + -0.021733446046710014, + 0.023898839950561523, + -0.11254694312810898, + -0.06519465893507004, + 0.04424642026424408, + 0.09124527126550674, + 0.006083414424210787, + 0.09144245833158493, + 0.02653978019952774, + -0.01318738516420126, + 0.0480327382683754, + -3.0391063887691416e-08, + 0.051376331597566605, + -0.0002709411783143878, + -0.03103259764611721, + -0.018394535407423973, + 0.05002995952963829, + 0.05086217448115349, + -0.07317503541707993, + -0.0172730665653944, + -0.08379635214805603, + 0.1180257499217987, + 0.08445936441421509, + -0.025030585005879402, + -0.01965731382369995, + 0.046042654663324356, + 0.03724817931652069, + 0.028524605557322502, + 0.061249297112226486, + -0.027382537722587585, + -0.0011134583037346601, + -0.001871297718025744, + -0.04395337030291557, + 0.002261978341266513, + 0.06950556486845016, + -0.024213269352912903, + -0.0782783254981041, + -0.10320401936769485, + -0.022083906456828117, + -0.04333319142460823, + -0.0334695503115654, + 0.007842703722417355, + -0.03523677587509155, + 0.08107997477054596, + 0.00924254022538662, + -0.013395791873335838, + -0.019067300483584404, + -0.008446489460766315, + -0.1053837463259697, + 0.06697141379117966, + 0.06984667479991913, + 0.007155571132898331, + -0.038544610142707825, + 0.0132181691005826, + -0.004773592576384544, + -0.022143904119729996, + -0.09064015746116638, + -0.07600560784339905, + -0.042070601135492325, + -0.08189931511878967, + 0.03302472084760666, + 0.043238356709480286, + -0.01407547201961279, + -0.03778013586997986, + 0.030578600242733955, + 0.021573437377810478, + 0.04664295166730881, + 0.056082408875226974, + -0.07687672227621078, + -0.0018553169211372733, + -0.051700614392757416, + 0.043752558529376984, + -0.02636834792792797, + 0.05589277669787407, + 0.05282546952366829, + -0.016411008313298225 + ], + "model": "Jigger", + "pickup_zone": "POLYGON((-74.0610 40.7578, -73.9510 40.7578, -73.9510 40.6678, -74.0610 40.6678, -74.0610 40.7578))", + "price": 270, + "store_location": "-74.0060,40.7128" + }, + { + "brand": "Bicyk", + "condition": "used", + "description": "Kids want to ride with as little weight as possible. Especially on an incline! They may be at the age when a 27.5\" wheel bike is just too clumsy coming off a 24\" bike. The Hillcraft 26 is just the solution they need!", + "description_embeddings": [ + -0.004883771762251854, + 0.08099519461393356, + -0.022444017231464386, + 0.05437565594911575, + -0.07422323524951935, + 0.0066548739559948444, + -0.06268022209405899, + 0.042389899492263794, + -0.03745086118578911, + 0.058961447328329086, + 0.025613723322749138, + -0.04209878668189049, + 0.06861244142055511, + 0.01983577199280262, + 0.026353053748607635, + 0.045618414878845215, + 0.040685027837753296, + 0.09574265778064728, + 0.005801026243716478, + -0.027659950777888298, + -0.0223013274371624, + 0.040641166269779205, + 0.06608107686042786, + 0.0691058486700058, + -0.03629102557897568, + 0.035505786538124084, + -0.09211395680904388, + -0.011358118616044521, + -0.025078972801566124, + -0.017709167674183846, + 0.07587391883134842, + 0.08128049969673157, + 0.060521550476551056, + -0.0845090001821518, + -0.03779749944806099, + 0.030346086248755455, + 0.017926080152392387, + 0.003489845432341099, + -0.05622200667858124, + -0.06886664777994156, + -0.051538050174713135, + 0.029196197167038918, + -0.0028146395925432444, + 0.012419342994689941, + -0.06346380710601807, + -0.011617675423622131, + 0.04980290308594704, + -0.0799335315823555, + 0.016635078936815262, + 0.07064730674028397, + 0.04530491679906845, + -0.04372858256101608, + 0.07056037336587906, + -0.05052798613905907, + -0.01064316462725401, + -0.04754374921321869, + -0.08878123015165329, + 0.005363269243389368, + 0.032587066292762756, + -0.05610528588294983, + -0.0012875061947852373, + -0.03215320408344269, + -0.0045777312479913235, + -0.026692084968090057, + -0.09758491814136505, + -0.046251099556684494, + 0.03897765651345253, + -0.06587375700473785, + -0.013586618937551975, + -0.020807752385735512, + 0.023367363959550858, + 0.011167124845087528, + 0.003386110533028841, + -0.024887114763259888, + -0.029615335166454315, + -0.02571641281247139, + -0.03150812163949013, + -0.0395360104739666, + -0.049686528742313385, + -0.023117102682590485, + -0.07580453157424927, + 0.020851964130997658, + 0.0917917937040329, + -0.038357049226760864, + 0.05106140300631523, + -0.03367459401488304, + 0.05801103636622429, + 0.0628814697265625, + 0.024997225031256676, + 0.015594316646456718, + -0.01490987278521061, + 0.07070998847484589, + -0.039144083857536316, + 0.0657331570982933, + -0.053744420409202576, + -0.01675831526517868, + -0.008745769970119, + -0.07664742320775986, + -0.06751038879156113, + 0.0023392336443066597, + 0.018902592360973358, + 0.06754770874977112, + 0.07430258393287659, + 0.0806465670466423, + -0.031056180596351624, + 0.06557579338550568, + 0.06529161334037781, + -0.03742394223809242, + 0.0007822285988368094, + 0.10523669421672821, + 0.0038901956286281347, + -0.014934191480278969, + 0.0647430568933487, + 0.03438747301697731, + -0.046527378261089325, + 0.014247977174818516, + -0.020184241235256195, + 0.016480082646012306, + -0.05491460859775543, + 0.07232335209846497, + -0.016330908983945847, + 0.011368552222847939, + -0.001964043825864792, + 0.0009170984267257154, + 0.019140562042593956, + -0.002758787479251623, + -0.05629577115178108, + 1.7957766384702998e-33, + -0.10579885542392731, + 0.08271613717079163, + 0.03821941837668419, + 0.06078806892037392, + 0.017647448927164078, + -0.07404755055904388, + 0.06083450838923454, + -0.07097837328910828, + -0.01949647255241871, + -0.005204185377806425, + 0.0160058680921793, + -0.03624944016337395, + 0.065463587641716, + -0.04834574833512306, + 0.09314870834350586, + -0.022509299218654633, + -0.047614336013793945, + -0.042122796177864075, + 0.0014064351562410593, + 0.08215921372175217, + 0.0144058121368289, + -0.08526691794395447, + -0.01885370910167694, + 0.020506983622908592, + -0.0041589876636862755, + -0.0928102508187294, + 0.0965222716331482, + 0.05469893291592598, + 0.002785224001854658, + 0.006347258575260639, + -0.09394793212413788, + -0.08587668836116791, + 0.00999284815043211, + -0.015109539031982422, + 0.035454027354717255, + -0.08842843770980835, + -0.015698572620749474, + 0.05549640208482742, + -0.011119373142719269, + 0.012295924127101898, + 0.007523554377257824, + -0.03497130423784256, + -0.05309790000319481, + -0.021819932386279106, + 0.011010204441845417, + 0.0778549313545227, + 0.122015580534935, + 0.0451776348054409, + -0.0894458070397377, + 0.0031173918396234512, + -0.003828236600384116, + 0.0010151821188628674, + 0.0007775757694616914, + -0.0007406148943118751, + 0.0005911831394769251, + 0.029611686244606972, + -0.010095393285155296, + -0.015750357881188393, + -0.08871200680732727, + 0.06563369184732437, + 0.052563928067684174, + -0.02150006778538227, + 0.032858334481716156, + -0.039781685918569565, + -0.02986454777419567, + -0.017254218459129333, + 0.013349524699151516, + 0.04903600737452507, + -0.102760910987854, + 0.027411801740527153, + -0.007306735496968031, + 0.03547230362892151, + 0.03793823719024658, + -0.014224819839000702, + 0.004229242447763681, + -0.04914051666855812, + -0.05566011741757393, + -0.08426816016435623, + 0.0378078892827034, + -0.02177048847079277, + 0.037800222635269165, + 0.01145790982991457, + -0.03493969514966011, + -0.06417357921600342, + -0.04812582954764366, + -0.030254419893026352, + -0.12552082538604736, + 0.0017056012293323874, + -0.053679559379816055, + 0.019939688965678215, + -0.04766315221786499, + -0.143480584025383, + -0.024615854024887085, + 0.06507551670074463, + 0.01710103265941143, + -2.55080180279124e-33, + -0.01073896698653698, + 0.08023330569267273, + 0.028500312939286232, + -0.033364687114953995, + 0.018465891480445862, + -0.018969086930155754, + 0.116150863468647, + -0.04905116185545921, + 0.0067994301207363605, + -0.051097989082336426, + -0.047208935022354126, + 0.003005147911608219, + -0.006951641291379929, + 0.0299075860530138, + 0.023957515135407448, + 0.005555577110499144, + -0.020836569368839264, + 0.013542957603931427, + 0.09286782890558243, + -0.04009733721613884, + 0.05567550286650658, + 0.01991306059062481, + -0.16575683653354645, + -0.003300475887954235, + 0.11635366082191467, + 0.008300523273646832, + -0.1112738847732544, + 0.05307481065392494, + 0.009467027150094509, + 0.11263766884803772, + -0.04102758690714836, + -0.0505208782851696, + 0.1890914887189865, + -0.01593983918428421, + 0.011381726711988449, + 0.01095605455338955, + -0.08038999140262604, + -0.012621873058378696, + -0.005316049326211214, + 0.017261112108826637, + 0.03283751755952835, + -0.04533768445253372, + 0.03397509828209877, + 0.04211656376719475, + 0.024692395702004433, + -0.02541458234190941, + 0.02313675545156002, + 0.02338019199669361, + -0.011879520490765572, + -0.05438990890979767, + 0.03806900233030319, + 0.01261812262237072, + 0.02512892708182335, + -0.0028746703173965216, + -0.016077643260359764, + -0.032072994858026505, + -0.006427581422030926, + 0.01777057908475399, + 0.02934812381863594, + -0.05759994685649872, + -2.871774631785229e-05, + -0.03137838840484619, + -0.06273766607046127, + 0.04409930482506752, + -0.05993351340293884, + 0.007546861190348864, + 0.0053585791029036045, + 0.042325496673583984, + -0.007369876839220524, + 0.04489513114094734, + -0.12103329598903656, + 0.017391694709658623, + 0.0304956566542387, + -0.034047987312078476, + 0.02484256401658058, + -0.06834809482097626, + 0.06508748978376389, + 0.08324999362230301, + -0.020252887159585953, + -0.014722783118486404, + 0.02126440405845642, + -0.05160334333777428, + 0.045947108417749405, + 0.022960059344768524, + 0.023375188931822777, + -0.060902271419763565, + -0.05150751397013664, + -0.1094929575920105, + -0.04899677261710167, + 0.09132419526576996, + 0.051848214119672775, + -0.0077659315429627895, + 0.0012422297149896622, + 0.058530740439891815, + 0.040777210146188736, + -3.354356081786136e-08, + 0.025891084223985672, + -0.04088461399078369, + -0.06885679066181183, + 0.01951301097869873, + 0.047974348068237305, + 0.04472370818257332, + 0.004657004959881306, + 0.001041706302203238, + -0.02763887122273445, + 0.03814717009663582, + 0.03166148066520691, + 0.0063626947812736034, + 0.09577886760234833, + 0.06234167888760567, + 0.0010398400481790304, + 0.010609040968120098, + 0.020408503711223602, + 0.05596008151769638, + 0.00923844799399376, + 0.011290326714515686, + 0.02393697388470173, + -0.03378620743751526, + 0.010788901709020138, + 0.0072112190537154675, + -0.03552679717540741, + -0.10475718975067139, + 0.003995304461568594, + -0.002284976886585355, + -0.014504319056868553, + -0.06887608021497726, + 0.03398992121219635, + -0.005206231493502855, + 0.049566611647605896, + 0.00902023445814848, + 0.06874160468578339, + 0.014804325066506863, + -0.07230424880981445, + 0.0428827665746212, + 0.013657039031386375, + 0.027973631396889687, + -0.035619381815195084, + 0.06485525518655777, + -0.06238642707467079, + -0.012459578923881054, + 0.020500177517533302, + -0.0715484470129013, + -0.16523504257202148, + 0.013638298027217388, + 0.07008316367864609, + 0.026970835402607918, + 0.004871702753007412, + -0.0012540861498564482, + -0.028708957135677338, + 0.05812879279255867, + 0.12611250579357147, + 0.09877888858318329, + -0.04118988662958145, + -0.02214396744966507, + -0.10328112542629242, + 0.029945021495223045, + 0.004513312131166458, + 0.011272193863987923, + 0.03294430673122406, + -0.042709026485681534 + ], + "model": "Hillcraft", + "pickup_zone": "POLYGON((-118.2887 34.0972, -118.1987 34.0972, -118.1987 33.9872, -118.2887 33.9872, -118.2887 34.0972))", + "price": 1200, + "store_location": "-118.2437,34.0522" + }, + { + "brand": "Nord", + "condition": "used", + "description": "The Chook Air 5 gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. The lower top tube makes it easy to mount and dismount in any situation, giving your kids greater safety on the trails.", + "description_embeddings": [ + -0.0018494834657758474, + 0.057690851390361786, + 0.038153987377882004, + 0.06570218503475189, + 0.028856752440333366, + -0.062333013862371445, + -0.014953209087252617, + 0.046022992581129074, + -0.08184631168842316, + 0.03648914024233818, + 0.03869181126356125, + 0.010564669035375118, + -0.020310621708631516, + -0.04062078520655632, + -0.0125962495803833, + 0.14169928431510925, + 0.03418859466910362, + -0.06641822308301926, + 0.005633663386106491, + -0.09943458437919617, + 0.023237863555550575, + -0.04369724169373512, + 0.016574522480368614, + 0.07258585095405579, + 0.018674470484256744, + -0.05764088034629822, + -0.0795072391629219, + 0.04034125804901123, + -0.036483921110630035, + -0.033106740564107895, + 0.02980787307024002, + -0.0028512384742498398, + 0.00786224752664566, + -0.03016488254070282, + -0.12349128723144531, + 0.031072411686182022, + 0.08362030982971191, + 0.025227056816220284, + -0.030982907861471176, + -0.006486377213150263, + -0.023590318858623505, + -0.03374557942152023, + -0.04145599156618118, + -0.09421771764755249, + -0.0013142612297087908, + -0.003397064981982112, + -0.0031338112894445658, + -0.11464792490005493, + 0.040542472153902054, + 0.02896481193602085, + 0.007327641360461712, + -0.06064218282699585, + 0.049546848982572556, + -0.05917377769947052, + -0.01963184028863907, + -0.002139812568202615, + -0.14361988008022308, + -0.05401389300823212, + 0.12506668269634247, + -0.07141950726509094, + -0.0032961040269583464, + 0.015251584351062775, + -0.05507654324173927, + -0.009836667217314243, + -0.02802908606827259, + -0.01053905300796032, + -0.03239851072430611, + -0.10646941512823105, + 0.03140658512711525, + 0.028125958517193794, + -0.004000179003924131, + -0.0018343725241720676, + 0.01727917790412903, + -0.013935663737356663, + -0.02435036562383175, + 0.04411163926124573, + -0.009158330969512463, + -0.023309389129281044, + 0.01229795441031456, + -0.04689493402838707, + -0.02138197235763073, + 0.013063939288258553, + 0.02832808345556259, + 0.031972818076610565, + 0.020882662385702133, + -0.015083174221217632, + 0.002903456799685955, + -0.047304242849349976, + -0.10658963769674301, + -0.06274145841598511, + -0.030370736494660378, + 0.0539257749915123, + 0.00848578754812479, + 0.02172423154115677, + -0.007691903971135616, + -0.10581931471824646, + 0.06078812852501869, + 0.007988635450601578, + -0.116583913564682, + 0.05237157270312309, + 0.024445366114377975, + -0.02832716703414917, + 0.04004029557108879, + 0.02844531089067459, + -0.0455174520611763, + -0.07379734516143799, + 0.09453199058771133, + -0.011599121615290642, + -0.0027194281574338675, + 0.014355232007801533, + -0.059690698981285095, + -0.012937567196786404, + 0.034315045922994614, + -0.047598548233509064, + -0.03261064738035202, + 0.05839747563004494, + -0.12691465020179749, + 0.03778312727808952, + 0.006131120957434177, + 0.04806787148118019, + -0.03441976010799408, + 0.08042734116315842, + 0.008934197947382927, + 0.027216315269470215, + 0.0016972541343420744, + -0.10113930702209473, + -0.0003218930505681783, + 9.75532108829862e-34, + -0.0537416972219944, + 0.06875170767307281, + -0.01566525548696518, + 0.01952524110674858, + -0.0005404680850915611, + -0.08984242379665375, + 0.04537447541952133, + -0.1295408457517624, + 7.603532867506146e-05, + 0.040753066539764404, + 0.016371281817555428, + 0.029906686395406723, + -0.005372706335037947, + -0.06687828153371811, + 0.11607439070940018, + 0.016209086403250694, + -0.11238335072994232, + -0.057236358523368835, + -0.09619198739528656, + 0.027146028354763985, + -0.09542766213417053, + -0.0360424630343914, + -0.09913153201341629, + 0.04242968559265137, + 0.05494842678308487, + -0.025294257327914238, + 0.06307625770568848, + 0.007745219860225916, + -0.019641151651740074, + 0.07056662440299988, + -0.05425839126110077, + 0.012385660782456398, + -0.006104010157287121, + -0.07186716794967651, + -0.10919132828712463, + -0.0017968777101486921, + 0.010471112094819546, + -0.011221444234251976, + -0.035078633576631546, + 0.009300827980041504, + 0.0802159234881401, + -0.10042990744113922, + -0.01718892529606819, + 0.05525779724121094, + -0.019847391173243523, + 0.08405174314975739, + 0.06403975188732147, + 0.0627448782324791, + -0.07871688157320023, + 0.0002676364383660257, + -0.05110163986682892, + 0.006078454665839672, + -0.019803548231720924, + -0.014253707602620125, + 0.039836447685956955, + 0.021812820807099342, + 0.00014793995069339871, + -0.006739508826285601, + -0.023166682571172714, + 0.05429920181632042, + 0.1337796151638031, + -0.01773720420897007, + 0.024304436519742012, + -0.016411837190389633, + -0.07777299731969833, + 0.042669400572776794, + 0.06226645037531853, + -0.023803485557436943, + 0.00396164134144783, + -0.049458179622888565, + -0.004774407483637333, + 0.036529600620269775, + 0.02002328634262085, + -0.02465248480439186, + -0.024076614528894424, + -0.03887653350830078, + 0.057176534086465836, + -0.03888818621635437, + -0.027698175981640816, + 0.001469603506848216, + 0.04755152389407158, + -0.0938708707690239, + 0.013991769403219223, + -0.026987746357917786, + -0.03277081623673439, + -0.04837489873170853, + 0.02711542509496212, + -0.09185922145843506, + -0.03453921154141426, + 0.03532274439930916, + -0.024472877383232117, + -0.09732313454151154, + 0.008513586595654488, + 0.03207352012395859, + 0.030766190961003304, + -2.5405224720352836e-33, + 0.08067575097084045, + -0.008160247467458248, + 0.03101508319377899, + 0.005022854544222355, + 0.0010000152979046106, + 0.06958161294460297, + 0.10594375431537628, + -0.06177408620715141, + -0.01650322414934635, + 0.03043895959854126, + -0.018333615735173225, + 0.06436911225318909, + 0.02439672127366066, + -0.01213911734521389, + 0.09937868267297745, + 0.02093592658638954, + -0.003140130080282688, + -0.016580305993556976, + 0.10430759936571121, + -0.019038936123251915, + 0.05574416741728783, + 0.07455366849899292, + -0.029936065897345543, + 0.0017704741330817342, + 0.07022519409656525, + 0.02108696848154068, + -0.050372399389743805, + 0.027957700192928314, + 0.005698348395526409, + 0.03494682535529137, + -0.02610155940055847, + -0.0068950653076171875, + 0.1346345692873001, + 0.03947756066918373, + -0.05966781824827194, + -0.010489783249795437, + -0.04099087417125702, + -0.027186688035726547, + -0.04620056599378586, + -0.02478279173374176, + -0.007060651201754808, + -0.023514581844210625, + 0.06082035228610039, + -0.05849218741059303, + -0.0036981222219765186, + 0.04169313609600067, + 0.09352244436740875, + 0.020741308107972145, + -0.0019505824893712997, + -0.10489305853843689, + 0.08789870887994766, + 0.039999835193157196, + -0.014334832318127155, + 0.008347390219569206, + 0.03113699145615101, + 0.10894497483968735, + 0.027165820822119713, + 0.0064145540818572044, + -0.00803150050342083, + -0.055484138429164886, + -0.03251631557941437, + 0.02290980890393257, + 0.04825572296977043, + 0.01608354039490223, + -0.04969468340277672, + -0.004120110999792814, + -0.03278858959674835, + 0.009696378372609615, + -0.04376300796866417, + -0.0009336083312518895, + -0.0313178189098835, + -0.05882050469517708, + 0.057815250009298325, + -0.02050788328051567, + -0.024381538853049278, + 0.06283771246671677, + 0.06954411417245865, + 0.09720556437969208, + -0.056403111666440964, + -0.04526498168706894, + -0.07259991019964218, + 0.001844316371716559, + 0.04090375825762749, + 0.06941819936037064, + -0.041316937655210495, + 0.002292247023433447, + -0.03425106778740883, + -0.0628972053527832, + 0.0063382769003510475, + 0.09668626636266708, + 0.062228571623563766, + 0.03658486530184746, + -0.08789398521184921, + 0.0009696391643956304, + -0.004108588211238384, + -3.183854957455878e-08, + 0.09346635639667511, + 0.042943451553583145, + -0.0005091542261652648, + 0.026524608954787254, + 0.009858721867203712, + 0.03737989068031311, + -0.014056878164410591, + 0.038327474147081375, + -0.010239921510219574, + 0.05757640674710274, + 0.014411918818950653, + 0.038742948323488235, + 0.06475342065095901, + -0.0011537548853084445, + -0.017729472368955612, + 0.05167960748076439, + 0.024419916793704033, + 0.08681508898735046, + 0.015235288999974728, + 0.036676522344350815, + -0.03421042487025261, + -0.019762659445405006, + 0.09467294812202454, + -0.053133491426706314, + -0.04356615990400314, + -0.03919585049152374, + 0.015591761097311974, + 0.021372869610786438, + -0.0058142030611634254, + -0.022864477708935738, + -0.02901598811149597, + 0.0458187572658062, + -0.030826766043901443, + -0.008975986391305923, + 0.03365883231163025, + -0.010484383441507816, + -0.1445801854133606, + 0.05828193947672844, + -0.028194306418299675, + 0.05975533276796341, + 0.014028828591108322, + 0.0036430624313652515, + 0.024983061477541924, + 0.01454286277294159, + -0.006972659844905138, + 0.037446193397045135, + -0.06949692964553833, + -0.09630566090345383, + 0.03263894096016884, + 0.048720087856054306, + -0.06886433064937592, + 0.018142051994800568, + 0.03894415125250816, + 0.05843216925859451, + 0.06860719621181488, + 0.04971907287836075, + -0.025701280683279037, + -0.06293400377035141, + -0.05422094464302063, + 0.01912975125014782, + 0.009564549662172794, + 0.055643752217292786, + -0.0027948219794780016, + 0.0329461470246315 + ], + "model": "Chook air 5", + "pickup_zone": "POLYGON((-87.6848 41.9331, -87.5748 41.9331, -87.5748 41.8231, -87.6848 41.8231, -87.6848 41.9331))", + "price": 815, + "store_location": "-87.6298,41.8781" + }, + { + "brand": "Eva", + "condition": "used", + "description": "The sister company to Nord, Eva launched in 2005 as the first and only women-dedicated bicycle brand. Designed by women for women, allEva bikes are optimized for the feminine physique using analytics from a body metrics database. If you like 29ers, try the Eva 291. It\u2019s a brand new bike for 2022.. This full-suspension, cross-country ride has been designed for velocity. The 291 has 100mm of front and rear travel, a superlight aluminum frame and fast-rolling 29-inch wheels. Yippee!", + "description_embeddings": [ + 0.035103436559438705, + 0.02666405402123928, + -0.06364161521196365, + 0.02551678754389286, + -0.005281867925077677, + -0.04041111096739769, + -0.020820949226617813, + -0.03485208749771118, + -0.07683732360601425, + 0.021527189761400223, + 0.007516156416386366, + -0.0034474905114620924, + 0.030465560033917427, + -0.06572654843330383, + -0.020914506167173386, + 0.032637566328048706, + 0.0815017819404602, + -0.022764643654227257, + 0.07385077327489853, + 0.058004263788461685, + -0.03062591142952442, + -0.03927106410264969, + 0.01410673838108778, + 0.05480317771434784, + -0.05647570267319679, + -0.008725483901798725, + -0.05373937636613846, + 0.03546926751732826, + -0.026455262675881386, + -0.09718386828899384, + -0.040623344480991364, + 0.03622450679540634, + 0.08971034735441208, + -0.038574062287807465, + -0.05105822533369064, + 0.021020587533712387, + 0.003312851767987013, + -0.008969941176474094, + -0.0568903312087059, + 0.033502694219350815, + -0.0578635074198246, + -0.03721226751804352, + -0.036668986082077026, + 0.0022641047835350037, + 0.038053013384342194, + 0.03350543603301048, + 0.05258995667099953, + -0.007619654294103384, + -0.05145309492945671, + 0.026286069303750992, + 0.09238694608211517, + -0.06733417510986328, + 0.05791507661342621, + -0.07623173296451569, + -0.0052175214514136314, + -0.04393303394317627, + -0.15249019861221313, + -0.019764462485909462, + -0.03331150859594345, + -0.11831824481487274, + 0.05683637782931328, + 0.01903577335178852, + -0.023615414276719093, + 0.04120348393917084, + -0.05669170990586281, + 0.002014430705457926, + 0.009953595697879791, + 0.008390115574002266, + -0.025982441380620003, + -0.05977262556552887, + 0.0611012764275074, + 0.010146236047148705, + -0.047625984996557236, + 0.09061623364686966, + 0.02551751770079136, + 0.06041749566793442, + 0.1113404780626297, + 0.017673874273896217, + -0.05184035003185272, + 0.023109234869480133, + -0.04408435523509979, + -0.09029985964298248, + 0.06733208149671555, + 0.049696795642375946, + 0.05554559826850891, + 0.01563390903174877, + -0.019527558237314224, + -0.014796985313296318, + 0.003595865098759532, + 0.012917418964207172, + -0.06858907639980316, + -0.008697138167917728, + 0.04721860587596893, + 0.03153855353593826, + -0.05275731533765793, + 0.019923491403460503, + -0.009707989171147346, + -0.018920045346021652, + 0.03773808106780052, + 0.042773403227329254, + -0.03819388151168823, + 0.04029008001089096, + 0.060834936797618866, + 0.07531940191984177, + -0.04695741459727287, + 0.00488079572096467, + 0.13518987596035004, + -0.014429144561290741, + 0.0314130075275898, + 0.04135369136929512, + -0.021350333467125893, + -0.01289785373955965, + 0.032701168209314346, + -0.037027571350336075, + -0.018168980255723, + -0.07188623398542404, + -0.036501020193099976, + 0.03303954005241394, + 0.10676111280918121, + -0.03277475759387016, + -0.06245853006839752, + -0.011879103258252144, + 0.0533418171107769, + -0.01446340698748827, + 0.03530410677194595, + 0.05820532143115997, + -0.0015766610158607364, + -8.477015062817539e-34, + -0.10837127268314362, + 0.015582970343530178, + 0.0182977095246315, + 0.055213626474142075, + -0.03584470599889755, + 0.02778925560414791, + 0.08698058873414993, + -0.04999695345759392, + -0.0842076763510704, + -0.040448326617479324, + -0.06311061233282089, + 0.02668358013033867, + 0.04676111042499542, + -0.006417605560272932, + 0.12788759171962738, + 0.02197197638452053, + 0.07035308331251144, + -0.04392284154891968, + -0.008788101375102997, + -0.001108768628910184, + 0.07960236072540283, + -0.0019975434988737106, + -0.010499294847249985, + 0.03599945828318596, + 0.02329486794769764, + -0.01962442137300968, + 0.15486162900924683, + 0.027215363457798958, + -0.022036811336874962, + 0.04227740690112114, + -0.07894206047058105, + -0.03180933743715286, + 0.020022651180624962, + -0.05859709531068802, + -0.0009564562351442873, + 0.009732870385050774, + -0.09007531404495239, + 0.041766807436943054, + 0.003291067900136113, + 0.0950121283531189, + 0.02693203091621399, + -0.01629827171564102, + -0.01884087361395359, + -0.029889501631259918, + -0.003714299062266946, + 0.09247232973575592, + 0.06151247024536133, + 0.09120925515890121, + -0.011266379617154598, + 0.03680066391825676, + -0.1628604233264923, + -0.008045083843171597, + -0.023876454681158066, + 0.046465914696455, + 0.01841152086853981, + 0.01759498566389084, + -0.012628139927983284, + 0.02123965509235859, + -0.07098977267742157, + 0.025028834119439125, + -0.032171521335840225, + 0.0538402758538723, + -0.00211805896833539, + -0.019548164680600166, + -0.046793293207883835, + 0.04394293949007988, + 0.022090770304203033, + -0.058215122669935226, + -0.05101722851395607, + 0.014057288877665997, + -0.05860457569360733, + 0.006166193168610334, + 0.04641130194067955, + 0.03165149688720703, + 0.045289356261491776, + 0.038580797612667084, + -0.0335664264857769, + 0.013378577306866646, + 0.058321163058280945, + -0.03730795532464981, + -0.01996016688644886, + 0.025774186477065086, + 0.001352976425550878, + 0.023636724799871445, + 0.026727410033345222, + -0.0730309784412384, + -0.01613243669271469, + -0.009525856003165245, + -0.03985843434929848, + -0.003976964857429266, + -0.006743384525179863, + -0.06324627995491028, + 0.03959967568516731, + 0.021898096427321434, + -0.004184887744486332, + -3.110083923319741e-34, + 0.03726857528090477, + -0.016945818439126015, + 0.05512943118810654, + 0.0471712127327919, + 0.097488172352314, + 0.02456829510629177, + 0.08276744186878204, + -0.02230781689286232, + -0.03785759210586548, + 0.010082835331559181, + 0.07151538133621216, + -0.04426267370581627, + 0.03402319550514221, + 0.05808456242084503, + 0.07566764950752258, + 0.07006501406431198, + 0.002404613886028528, + -0.10078012198209763, + 0.0029093879275023937, + -0.12370351701974869, + -0.03431423008441925, + 0.08334372937679291, + 0.001441179309040308, + -0.08001153916120529, + 0.020076438784599304, + 0.011177998036146164, + 0.034560561180114746, + 0.041609298437833786, + -0.04921843111515045, + 0.03598331660032272, + -0.10671709477901459, + 0.02969883382320404, + 0.048317357897758484, + 0.12375228852033615, + 0.040479566901922226, + 0.0330270379781723, + -0.06994733214378357, + 0.008698385208845139, + 0.03447363153100014, + -0.012882913462817669, + -0.02672695368528366, + -0.06423910707235336, + -0.0506032295525074, + 0.0053747911006212234, + 0.0682206079363823, + -0.005316274706274271, + 0.027013784274458885, + -0.006269444711506367, + 0.08528510481119156, + -0.0731915608048439, + 0.0046186731196939945, + -0.024244142696261406, + 0.0360478051006794, + 0.020591434091329575, + 0.04302601516246796, + -0.14392279088497162, + 0.05873512104153633, + -0.010028650052845478, + -0.04548479616641998, + -0.013535127975046635, + 0.01113649271428585, + 0.028603754937648773, + -0.04036158323287964, + 0.0704532265663147, + -0.09373150765895844, + -0.07198052108287811, + -0.002203285926952958, + -0.0855080857872963, + -0.08842256665229797, + -9.343179408460855e-05, + -0.029457710683345795, + -0.02197202481329441, + -0.048936717212200165, + 0.06165122613310814, + -0.0626755878329277, + 0.009602922946214676, + 0.07251632958650589, + 0.03113914094865322, + -0.0010769155342131853, + -0.040936876088380814, + -0.04328843951225281, + -0.020654935389757156, + 0.08143945783376694, + 0.03210373967885971, + 0.03849901258945465, + 0.08388370275497437, + -0.04882088676095009, + -0.04764509201049805, + -0.01594746671617031, + 0.08005915582180023, + -0.0007682700525037944, + 0.04356953501701355, + -0.08784972876310349, + -0.009003485552966595, + -0.012332507409155369, + -3.9398202034135466e-08, + 0.006421600468456745, + 0.04334808140993118, + 0.0013437344459816813, + -0.009495558217167854, + -0.022657591849565506, + -0.012704327702522278, + 0.018703341484069824, + -0.07545771449804306, + -0.07807240635156631, + 0.0031038280576467514, + -0.023932253941893578, + 0.040701914578676224, + 0.10603249073028564, + 0.03773405775427818, + 0.05925403907895088, + -0.02083730883896351, + 0.052759915590286255, + 0.08195225894451141, + -0.057340435683727264, + -0.03538660705089569, + 0.04492119327187538, + -0.07101765275001526, + 0.02868317998945713, + -0.11165601015090942, + -0.03126508370041847, + -0.07953942567110062, + -0.022893071174621582, + -0.08839578926563263, + 0.00727836275473237, + -0.08685773611068726, + 0.026177138090133667, + 0.028831886127591133, + 0.03626682609319687, + -0.045381225645542145, + -0.013574030250310898, + 0.028583087027072906, + -0.004301569424569607, + 0.04326719045639038, + -0.023370176553726196, + 0.057897310703992844, + -0.029195263981819153, + -0.001789534231647849, + 0.032133687287569046, + 0.003419605316594243, + 0.028055502101778984, + -0.0038284522015601397, + -0.022835813462734222, + -0.07568305730819702, + 0.017481982707977295, + 0.013085611164569855, + 0.009357997216284275, + -0.030347391963005066, + -0.0020967889577150345, + 0.03544173017144203, + 0.004640925209969282, + 0.025202661752700806, + -0.0916307270526886, + -0.06341513246297836, + -0.017053432762622833, + 0.06747056543827057, + 0.0467485710978508, + -0.14364545047283173, + 0.024641912430524826, + -0.04414863884449005 + ], + "model": "Eva 291", + "pickup_zone": "POLYGON((-80.2433 25.8067, -80.1333 25.8067, -80.1333 25.6967, -80.2433 25.6967, -80.2433 25.8067))", + "price": 3400, + "store_location": "-80.1918,25.7617" + }, + { + "brand": "Noka Bikes", + "condition": "used", + "description": "Whether you want to try your hand at XC racing or are looking for a lively trail bike that's just as inspiring on the climbs as it is over rougher ground, the Wilder is one heck of a bike built specifically for short women. Both the frames and components have been tweaked to include a women\u2019s saddle, different bars and unique colourway.", + "description_embeddings": [ + 0.07420087605714798, + -0.01575474441051483, + 0.010670951567590237, + 0.07449527084827423, + 0.0060751838609576225, + 0.03211340680718422, + -0.008086569607257843, + 0.025549469515681267, + -0.07154879719018936, + 0.014914358966052532, + -0.030715830624103546, + -0.0064881909638643265, + -0.0071744490414857864, + -0.0495535172522068, + 0.03856685757637024, + 0.056132566183805466, + 0.10794447362422943, + -0.010181701742112637, + 0.0811777114868164, + 0.10135157406330109, + -0.0769873708486557, + -0.019640743732452393, + -0.028702793642878532, + 0.07654724270105362, + -0.07045057415962219, + -0.10104052722454071, + -0.004679638426750898, + -0.0027665267698466778, + 0.030919065698981285, + -0.05461210012435913, + -0.020669877529144287, + 0.031864751130342484, + 0.0835040882229805, + -0.05930671840906143, + -0.006361816544085741, + -0.044132985174655914, + 0.035945694893598557, + -0.0027891425415873528, + -0.07598478347063065, + -0.03105698712170124, + -0.059601303189992905, + -0.018435664474964142, + -0.03314891457557678, + 0.06877987831830978, + -0.016064301133155823, + 0.01545438077300787, + 0.056307148188352585, + -0.08382677286863327, + -0.05274924635887146, + 0.01139853335916996, + 0.10750263929367065, + -0.004042057786136866, + 0.003356053726747632, + -0.01083006989210844, + -0.06153054162859917, + -0.054990023374557495, + -0.1360272616147995, + 0.025806479156017303, + 0.043233320116996765, + -0.009591769427061081, + 0.04422037675976753, + 0.02436559833586216, + -0.0012137923622503877, + -0.015348327346146107, + 0.02425999939441681, + -0.03409525752067566, + -0.08487176895141602, + 0.017345253378152847, + 0.035498712211847305, + -0.05615586042404175, + 0.02745831571519375, + 0.04017677903175354, + -0.0936250239610672, + 0.048734042793512344, + 0.024287866428494453, + -0.030274393036961555, + 0.08800201117992401, + 0.0879313051700592, + -0.0550895519554615, + -0.0026407642289996147, + -0.09552258998155594, + -0.05870680510997772, + 0.09009534120559692, + 0.05674433708190918, + 0.05360940843820572, + -0.0023017164785414934, + 0.005036584101617336, + -0.017987212166190147, + -0.05129106715321541, + -0.0012550759129226208, + -0.05818512290716171, + 0.06725005060434341, + 0.02540011890232563, + 0.054589059203863144, + 0.01723511517047882, + -0.04752320423722267, + 0.10586173087358475, + 0.05530202388763428, + -0.03287632390856743, + 0.05258375406265259, + 0.01655220240354538, + 0.011849797330796719, + 0.032285332679748535, + 0.03760116547346115, + -0.017522728070616722, + -0.05457543954253197, + 0.006817341782152653, + -0.028400525450706482, + -0.0027318967040628195, + -0.04200681298971176, + -0.026171568781137466, + -0.03272707015275955, + 0.016305547207593918, + 0.01545319240540266, + 0.0056663742288947105, + -0.0977277085185051, + -0.0009383464348502457, + -0.005693590268492699, + 0.039240892976522446, + 0.01645808108150959, + -0.01950509287416935, + 0.007762903813272715, + -0.004406424704939127, + 0.016364052891731262, + -0.006125410553067923, + -0.029666034504771233, + 0.044946398586034775, + 1.8357034061219326e-33, + -0.053835414350032806, + 0.03495992720127106, + -0.05977822467684746, + -0.009059705771505833, + 0.004659880883991718, + 0.022712793201208115, + 0.04409413039684296, + -0.10094501823186874, + -0.08702167868614197, + 0.0066354661248624325, + 0.011878615245223045, + 0.0033176038414239883, + -0.012380938045680523, + 0.0010130798909813166, + 0.0644172728061676, + -0.07130810618400574, + -0.0045928386971354485, + -0.03375661373138428, + -0.022520871832966805, + 0.07504180818796158, + 0.009861051104962826, + 0.07191396504640579, + -0.014361198991537094, + 0.01449025422334671, + -0.010663183405995369, + -0.028888769447803497, + 0.09297508746385574, + 0.04386264830827713, + -0.09579017758369446, + 0.007718369830399752, + -0.11800525337457657, + -0.020133504644036293, + -0.0034684871789067984, + -0.03735410049557686, + 0.006975250784307718, + -0.012902614660561085, + 0.04201272875070572, + 0.04273228347301483, + -0.07133302837610245, + 0.09145014733076096, + 0.0048939259722828865, + -0.058044496923685074, + -0.017591776326298714, + -0.03502552956342697, + -0.05678534135222435, + 0.05471408739686012, + 0.09568087011575699, + 0.09486310184001923, + -0.045761823654174805, + 0.018188882619142532, + -0.12331638485193253, + -0.023129422217607498, + -0.05455191433429718, + 0.06732556223869324, + 0.048286039382219315, + -0.0014048831071704626, + 0.03308422118425369, + -0.009839850477874279, + -0.05661558359861374, + 0.03290552645921707, + 0.03661618381738663, + 0.0047610136680305, + -0.05254451557993889, + 0.006052205804735422, + -0.13153813779354095, + -0.006893055979162455, + 0.037368785589933395, + -0.03058353252708912, + -0.0017269864911213517, + -0.008851475082337856, + -0.0740399956703186, + 0.057353563606739044, + 0.12296456098556519, + 0.0413251556456089, + 0.09911972284317017, + 0.016817500814795494, + -0.048074446618556976, + 0.05658562108874321, + -0.012700358405709267, + -0.08663205802440643, + 0.0014393541496247053, + 0.00613820506259799, + -0.04446813836693764, + 0.04673916846513748, + -0.02757285162806511, + -0.05133393779397011, + -0.028082016855478287, + -0.04668722674250603, + -0.03849129378795624, + -0.047927819192409515, + -0.06503037363290787, + -0.08361010253429413, + 0.0393000952899456, + 0.04658354073762894, + 0.009724845178425312, + -2.0251938301584547e-33, + 0.07265108078718185, + -0.04307040572166443, + 0.04996086284518242, + 0.03520473092794418, + 0.1084771379828453, + 0.005833788774907589, + 0.046216338872909546, + -0.04042917117476463, + -0.04179416596889496, + 0.03598152473568916, + 0.04082870855927467, + -0.10612837225198746, + -0.010728210210800171, + 0.03610331192612648, + 0.027484672144055367, + -0.008130725473165512, + 0.026157474145293236, + -0.07420457899570465, + 0.025218356400728226, + -0.0898737907409668, + -0.02742879092693329, + 0.03535477817058563, + -0.062408916652202606, + -0.1569257229566574, + -0.018789052963256836, + 0.04845775291323662, + -0.015149657614529133, + -0.0018356313230469823, + -0.04590461030602455, + 0.023325689136981964, + -0.13069787621498108, + -0.01994006149470806, + -0.021577563136816025, + -0.0231519415974617, + -0.002478161361068487, + 0.022444186732172966, + -0.04681165888905525, + 0.02769998274743557, + 0.003438781714066863, + 0.03829822316765785, + 0.0243418887257576, + -0.020368436351418495, + -0.005010040942579508, + 0.04648580029606819, + 0.061260052025318146, + 0.03784928843379021, + 0.008547516539692879, + 0.027585946023464203, + 0.043608926236629486, + 0.047329846769571304, + 0.10433284938335419, + 0.0069401939399540424, + 0.043503858149051666, + 0.06499945372343063, + -0.01040438748896122, + -0.11596397310495377, + 0.06451629102230072, + 0.032956890761852264, + 0.0007023254293017089, + 0.0898808017373085, + -0.055529963225126266, + -0.006572310347110033, + -0.06089714914560318, + 0.022685443982481956, + -0.0013110691215842962, + -0.09440209716558456, + -0.03121936321258545, + -0.003408250631764531, + -0.08051110059022903, + 0.01802976056933403, + 0.032015636563301086, + -9.986010991269723e-05, + -0.011806532740592957, + 0.06818002462387085, + 0.028290249407291412, + -0.005312844179570675, + 0.06016719341278076, + 0.014397598803043365, + 0.07122596353292465, + 0.007864296436309814, + 0.03002011403441429, + -0.05413847416639328, + 0.09744291007518768, + -0.01965983398258686, + 0.04150940105319023, + 0.14307892322540283, + -0.11320102959871292, + 0.03503091260790825, + 0.003515399992465973, + -0.023677969351410866, + 0.03955819085240364, + 0.0534457303583622, + 0.01904974691569805, + 0.031267836689949036, + -0.018026702105998993, + -3.930426117904062e-08, + 0.0003057526773773134, + 0.013398992829024792, + -0.10113491117954254, + -0.016498351469635963, + -0.00534934364259243, + 0.017148228362202644, + -0.03217773512005806, + -0.030934104695916176, + -0.06334194540977478, + 0.07242853194475174, + -0.0047585368156433105, + -0.01996637135744095, + -0.0016463182400912046, + 0.01777566224336624, + -0.04115547239780426, + 0.02906038798391819, + 0.10273877531290054, + 0.022776247933506966, + 0.030065912753343582, + -0.014570299535989761, + 0.047994960099458694, + -0.044575825333595276, + 0.025753378868103027, + -0.002644166350364685, + -0.09429919719696045, + -0.11280428618192673, + 0.021306486800312996, + 0.010426397435367107, + 0.021093064919114113, + -0.00363176385872066, + -0.024409662932157516, + 0.11473581194877625, + 0.0020395806059241295, + -0.08371622860431671, + -0.03764123469591141, + 0.039440982043743134, + -0.022172994911670685, + 0.0410802997648716, + -0.05086303874850273, + 0.053952641785144806, + -0.06084167957305908, + -0.036132071167230606, + 0.02080748789012432, + -0.043120622634887695, + 0.04048219695687294, + 0.05917482078075409, + 0.04085611552000046, + -0.05118294060230255, + 0.015727631747722626, + 0.01915580965578556, + 0.03531794995069504, + -0.058007121086120605, + 0.08498086780309677, + 0.0036822939291596413, + 0.018125539645552635, + 0.10145474225282669, + -0.05804500728845596, + -0.008451723493635654, + -0.029611116275191307, + 0.008798911236226559, + -0.03220565244555473, + -0.05617227777838707, + 0.03482669219374657, + -0.03508705273270607 + ], + "model": "Kahuna", + "pickup_zone": "POLYGON((-122.4644 37.8199, -122.3544 37.8199, -122.3544 37.7099, -122.4644 37.7099, -122.4644 37.8199))", + "price": 3200, + "store_location": "-122.4194,37.7749" + }, + { + "brand": "Breakout", + "condition": "new", + "description": "The XBN 2.1 Alloy is our entry-level road bike \u2013 but that\u2019s not to say that it\u2019s a basic machine. With an internal weld aluminium frame, a full carbon fork, and the slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.", + "description_embeddings": [ + -0.03482655808329582, + -0.024290302768349648, + 0.029588153585791588, + -0.04068901762366295, + 0.006173150148242712, + -0.06071849912405014, + 0.021348219364881516, + 0.032668184489011765, + -0.12000397592782974, + -0.026135660707950592, + -0.0262606181204319, + -0.014927615411579609, + 0.06986956298351288, + -0.006424048915505409, + -0.002834598533809185, + -0.005902229342609644, + 0.07471967488527298, + -0.10197333246469498, + 0.08836513012647629, + 0.0504477359354496, + 0.005102860741317272, + 0.0359189435839653, + -0.0477643720805645, + 0.02106260135769844, + 0.030146656557917595, + 0.04048784077167511, + -0.023416390642523766, + -0.0016326266340911388, + 0.039820387959480286, + -0.04475116729736328, + -0.03422572463750839, + 0.09266746789216995, + -0.04106999188661575, + -0.02442021667957306, + -0.006325263995677233, + -0.057226430624723434, + 0.12074039876461029, + 0.012658749707043171, + -0.09748225659132004, + -0.048439353704452515, + -0.004550903104245663, + -0.014449959620833397, + 0.03684601932764053, + 0.018772389739751816, + 0.09577438980340958, + 0.04358510673046112, + 0.06987427175045013, + -0.0561334528028965, + -0.03684744983911514, + 0.02584502473473549, + 0.039536770433187485, + -0.061133887618780136, + 0.05351594462990761, + -0.025124184787273407, + 0.09431525319814682, + 0.05062168091535568, + -0.11715397238731384, + 0.044368330389261246, + -0.024262988939881325, + -0.024561986327171326, + 0.036067184060811996, + 0.025171849876642227, + 0.033648427575826645, + 0.046933531761169434, + 0.09548858553171158, + -0.06253167241811752, + -0.045195333659648895, + -0.04183578118681908, + -0.040385909378528595, + -0.027590686455368996, + 0.08240272104740143, + -0.04743463918566704, + 0.004482025280594826, + 0.03219064325094223, + 0.0007497097249142826, + -0.04202196002006531, + 0.10904812812805176, + -0.06721051037311554, + -0.023717032745480537, + -0.01718866638839245, + -0.11568725854158401, + 0.038704562932252884, + 0.04929516091942787, + -0.03311185538768768, + -0.0017465045675635338, + -0.06153444945812225, + 0.019559966400265694, + -0.010708335787057877, + -0.06623212993144989, + 0.03114122338593006, + 0.03581896796822548, + 0.05368824675679207, + 0.016093581914901733, + -0.0077278027310967445, + 0.025581376627087593, + 0.02375067211687565, + -0.024797597900032997, + 0.08371419459581375, + -0.023117447271943092, + 0.04535554349422455, + -0.007224411237984896, + 0.06131899356842041, + 0.02283627539873123, + -0.052097078412771225, + -0.07922855019569397, + 0.0016958570340648293, + 0.051785532385110855, + 0.06701217591762543, + -0.02913537621498108, + 0.020526740700006485, + 0.03941992297768593, + -0.02217993699014187, + -0.08051256835460663, + -0.10155311226844788, + -0.05453299731016159, + -0.06470758467912674, + 0.002029003808274865, + -0.013401892967522144, + -0.011006158776581287, + 0.045922696590423584, + -0.040529411286115646, + 0.00991761963814497, + -0.06682797521352768, + 0.05892198532819748, + -0.028617633506655693, + -0.06339140236377716, + 0.0044001322239637375, + -4.362402064591546e-33, + -0.10147389024496078, + 0.039431530982255936, + -0.04599899426102638, + -0.049156975001096725, + -0.02249804697930813, + -0.026725362986326218, + 0.04369090870022774, + -0.0005211823736317456, + -0.030739039182662964, + -0.0065231663174927235, + 0.025333819910883904, + 0.10470504313707352, + 0.021332278847694397, + 0.05556178465485573, + 0.035125020891427994, + -0.1538446545600891, + 0.007054235320538282, + -0.036041803658008575, + 0.05932909622788429, + 0.0337519533932209, + 0.014841740019619465, + 0.030220910906791687, + 0.04296395927667618, + 0.02538421005010605, + -0.006869863253086805, + -0.0031259972602128983, + 0.11390665918588638, + -0.046557214111089706, + 0.00429841224104166, + 0.0428440123796463, + -0.1384042203426361, + 0.04695465788245201, + -0.0574827715754509, + -0.030760489404201508, + -0.07478123158216476, + -0.029447706416249275, + -0.06204935908317566, + -0.03058161959052086, + -0.02502700313925743, + -0.019530421122908592, + -0.02094511315226555, + -0.03218250721693039, + -0.05274674668908119, + -0.02680223248898983, + -0.01955571211874485, + 0.018619371578097343, + 0.007585515268146992, + 0.07155954837799072, + -0.018960801884531975, + -0.05782055854797363, + 0.017819860950112343, + 0.04109930992126465, + -0.03562675416469574, + 0.016705146059393883, + 0.0415029413998127, + 0.05103381723165512, + 0.035572972148656845, + -0.015020242892205715, + -0.03179502114653587, + 0.0891512930393219, + 0.007475084625184536, + 0.042234599590301514, + -0.0542532242834568, + 0.05480321869254112, + -0.10602187365293503, + 0.054763536900281906, + 0.04739809036254883, + -0.03327919542789459, + 0.0082072913646698, + -0.0650608167052269, + -0.08271145075559616, + -0.10922762006521225, + 0.03824940696358681, + 0.05978637561202049, + 0.10005365312099457, + 0.029007570818066597, + -0.034110404551029205, + 0.02545103058218956, + 0.05190473049879074, + -0.003596875350922346, + -0.08473207801580429, + 0.012021052651107311, + 0.018175840377807617, + 0.017920689657330513, + -0.03348258137702942, + 0.04048585146665573, + 0.030843179672956467, + 0.019531769677996635, + -0.00910205114632845, + 0.05721440538764, + 0.007200753781944513, + -0.11394353210926056, + 0.03483451530337334, + 0.029621547088027, + -0.03755185008049011, + 9.393710556981876e-34, + -0.009642334654927254, + -0.001342272269539535, + 0.01180787943303585, + 0.026348579674959183, + -0.011158440262079239, + -0.0019478596514090896, + 0.028490403667092323, + -0.052807874977588654, + -0.029139718040823936, + 0.08380713313817978, + 0.09657946228981018, + 0.00991911068558693, + 0.03502354025840759, + -0.016754556447267532, + 0.017460109665989876, + -0.01642783358693123, + 0.022211389616131783, + -0.008778599090874195, + 3.654864485724829e-05, + -0.09229966253042221, + 0.04083291441202164, + 0.08299239724874496, + -0.04151370748877525, + -0.05360836163163185, + -0.07950830459594727, + 0.03959093242883682, + -0.13340364396572113, + 0.054901909083127975, + 0.05736061558127403, + 0.04770279303193092, + -0.11388063430786133, + 0.0237369854003191, + 0.02305987849831581, + -0.013226242735981941, + -0.020716888830065727, + 0.03368164971470833, + -0.002396275522187352, + -0.012604329735040665, + -0.02715742215514183, + 0.0019254887010902166, + -0.00887741707265377, + -0.028728270903229713, + -0.05864499509334564, + 0.10937061905860901, + -0.004027256276458502, + 0.019197454676032066, + -0.03928225114941597, + -0.018220100551843643, + 0.02466396614909172, + 0.00980517640709877, + 0.05513712763786316, + 0.10625418275594711, + 0.08366440236568451, + -0.02691512741148472, + -0.026599230244755745, + -0.049529410898685455, + -0.05376818776130676, + -0.003328752936795354, + -0.04345694184303284, + 0.11166279017925262, + 0.0407760851085186, + -0.00792837142944336, + 0.03168283402919769, + -0.0018123856279999018, + 0.0357111431658268, + -0.1368872970342636, + 0.00755245191976428, + -0.010281031019985676, + -0.07121222466230392, + 0.03101137839257717, + 0.0662078782916069, + 0.007085337769240141, + -0.007063422352075577, + -0.05238816514611244, + -0.004185437690466642, + 0.00880429521203041, + 0.05528423562645912, + -0.08964741230010986, + 0.0042182342149317265, + -0.029020531103014946, + 0.014597366563975811, + 0.0002752764557953924, + 0.032267484813928604, + 0.11250412464141846, + 0.002768452512100339, + -0.026546282693743706, + 0.017761094495654106, + 0.023686127737164497, + -0.012699384242296219, + 0.018606871366500854, + -0.009665136225521564, + -0.06902427226305008, + -0.04932688549160957, + 0.051991984248161316, + -0.05918996408581734, + -4.18107468647122e-08, + -0.06375139951705933, + -0.0029491656459867954, + 0.032401617616415024, + -0.024946069344878197, + -0.026347795501351357, + 0.020192604511976242, + -0.025759287178516388, + 0.037004951387643814, + 0.043629322201013565, + 0.06278910487890244, + 0.02097572200000286, + -0.07064115256071091, + -0.005097216460853815, + 0.016486743465065956, + -0.0032796994782984257, + 0.07957274466753006, + 0.03776371479034424, + 0.04259084165096283, + -0.005312138702720404, + -0.11992045491933823, + 0.0859612300992012, + -0.0500827394425869, + 0.02553708106279373, + -0.052115052938461304, + -0.07368568331003189, + -0.11394031345844269, + -0.04513951390981674, + 0.022121727466583252, + -0.010451988317072392, + 0.003997989930212498, + -0.13713733851909637, + 0.030619636178016663, + 0.05786789208650589, + 0.05840904265642166, + 0.04732450470328331, + -0.012547117657959461, + -0.027409126982092857, + 0.049672048538923264, + -0.00018399256805423647, + -0.004273589234799147, + -0.011101006530225277, + 0.017240682616829872, + -0.002812016289681196, + 0.034935809671878815, + 0.006601597648113966, + 0.014211715199053288, + -0.06332860141992569, + -0.05397455021739006, + -0.038572490215301514, + -0.06450864672660828, + 0.07963147014379501, + 0.029951799660921097, + 0.03153093531727791, + -0.03852103650569916, + -0.025755248963832855, + 0.13077980279922485, + -0.08185151219367981, + -0.09442253410816193, + 0.01002975832670927, + 0.02509395219385624, + -0.029981056228280067, + -0.025097224861383438, + 0.04001101851463318, + 0.006130080670118332 + ], + "model": "XBN 2.1 Alloy", + "pickup_zone": "POLYGON((-0.1778 51.5524, 0.0822 51.5524, 0.0822 51.4024, -0.1778 51.4024, -0.1778 51.5524))", + "price": 810, + "store_location": "-0.1278,51.5074" + }, + { + "brand": "ScramBikes", + "condition": "new", + "description": "The WattBike is the best e-bike for people who still feel young at heart. It has a Bafang 1000W mid-drive system and a 48V 17.5AH Samsung Lithium-Ion battery, allowing you to ride for more than 60 miles on one charge. It\u2019s great for tackling hilly terrain or if you just fancy a more leisurely ride. With three working modes, you can choose between E-bike, assisted bicycle, and normal bike modes.", + "description_embeddings": [ + -0.006927311420440674, + 0.15900678932666779, + -0.005495064426213503, + 0.06652409583330154, + 0.027506737038493156, + 0.03928178921341896, + 0.0212758406996727, + 0.08142763376235962, + -0.004556896630674601, + 0.04261007905006409, + 0.0852041020989418, + -0.048658017069101334, + 0.04896014556288719, + 0.008289206773042679, + 0.09533551335334778, + 0.042673129588365555, + 0.11990982294082642, + -0.09381455183029175, + -0.001154645229689777, + -0.009989846497774124, + 0.042972203344106674, + 0.055328626185655594, + 0.044754382222890854, + 0.01764347031712532, + 0.04503790661692619, + -0.003830699948593974, + -0.03431522846221924, + 0.03080279380083084, + -0.07722456008195877, + -0.09261710941791534, + 0.04810558632016182, + 0.04917953535914421, + 0.027227703481912613, + -0.04199009761214256, + -0.11837311834096909, + 0.028090154752135277, + 0.08678824454545975, + -0.052036624401807785, + -0.06585966050624847, + -0.04037070646882057, + -0.08040877431631088, + 0.0018185328226536512, + 0.043989114463329315, + -0.011817573569715023, + 0.006730342749506235, + -0.011594205163419247, + 0.008361537009477615, + -0.054372794926166534, + 0.033345889300107956, + -0.03933562710881233, + 0.10115987062454224, + -0.08934503048658371, + 0.04519934952259064, + 0.03582148626446724, + -0.021424520760774612, + -0.07357319444417953, + -0.07426925748586655, + 0.018053170293569565, + 0.04639451205730438, + -0.07499486207962036, + 0.057791586965322495, + -0.05478687211871147, + 0.030340412631630898, + -0.0056327772326767445, + -0.0452428013086319, + -0.044913534075021744, + 0.0526629202067852, + -0.08259481936693192, + -0.05616062134504318, + 0.0005400424124673009, + -0.04933836683630943, + 1.7464293705415912e-05, + -0.007984945550560951, + 0.009467384777963161, + -0.04055757448077202, + -0.0056908270344138145, + 0.036597516387701035, + 0.023873118683695793, + 0.00418807053938508, + 0.04676923528313637, + -0.053795333951711655, + -0.015527212992310524, + -0.080276258289814, + 0.026996882632374763, + 0.1144171804189682, + -0.011178486980497837, + 0.06854862719774246, + 0.022201502695679665, + -0.01913747377693653, + 0.009713435545563698, + 0.01423699501901865, + 0.04772024229168892, + 0.034634001553058624, + 0.0756441131234169, + -0.01204933412373066, + -0.031088251620531082, + -0.02462930977344513, + -0.04386857897043228, + -0.07706759870052338, + -0.002071107504889369, + -0.019828464835882187, + 0.10314348340034485, + 0.07235224545001984, + 0.03167572245001793, + -0.02631053328514099, + -0.036559153348207474, + 0.012040914967656136, + 0.08063311874866486, + 0.008269569836556911, + -0.012434666976332664, + 0.00650354428216815, + -0.05601133033633232, + -0.028117282316088676, + -0.025071244686841965, + -0.01907099038362503, + 0.003760937135666609, + -0.052525606006383896, + 0.07173370569944382, + 0.09372185170650482, + 0.1006019189953804, + 0.023999499157071114, + 0.041847433894872665, + 0.02114962227642536, + 0.05726422369480133, + 0.008218048140406609, + -0.06967302411794662, + 0.01968124881386757, + 1.844028477519647e-33, + -0.031731415539979935, + 0.03648626059293747, + -0.026035945862531662, + -0.026796391233801842, + 0.009511047042906284, + 0.050696976482868195, + -0.03008556365966797, + -0.027142174541950226, + -0.07182826101779938, + -0.02520623430609703, + -0.005983793176710606, + 0.07632830739021301, + 0.09301365166902542, + 0.0744069442152977, + 0.10173527896404266, + -0.08317957073450089, + -0.06219454109668732, + -0.0776224136352539, + 0.013563201762735844, + 0.005839265417307615, + 0.011761599220335484, + -0.0701083242893219, + 0.005647188518196344, + -0.007439272943884134, + -4.4855809392174706e-05, + -0.05095696449279785, + 0.13620494306087494, + 0.017342044040560722, + -0.01352923084050417, + 0.03086051531136036, + -0.0740780308842659, + -0.06721310317516327, + -0.06769067794084549, + 0.01185466069728136, + -0.07234086841344833, + 0.0020215404219925404, + -0.0108563881367445, + 0.007788154762238264, + 0.07912690192461014, + -0.02952556498348713, + -0.010350959375500679, + 0.025074176490306854, + -0.050776757299900055, + 0.00947178341448307, + 0.03259417414665222, + 0.0319671556353569, + 0.0379379540681839, + 0.05242982879281044, + -0.07516643404960632, + 0.020074544474482536, + -0.08712191134691238, + -0.01204316969960928, + -0.006554455496370792, + -0.005875407252460718, + -0.06922540068626404, + 0.041081465780735016, + -0.003257623640820384, + 0.0391659140586853, + -0.03731334209442139, + -0.03579063341021538, + -0.04008869081735611, + 0.05648549646139145, + -0.01142149232327938, + -0.05515728518366814, + -0.06406072527170181, + -0.013155528344213963, + 0.0029902313835918903, + -0.020829875022172928, + -0.13008210062980652, + -0.039412979036569595, + 0.05974568799138069, + -0.06617670506238937, + 0.09968123584985733, + -0.04378099367022514, + 0.008272947743535042, + -0.007245620246976614, + -0.05228377878665924, + -0.05929296463727951, + -0.07816570997238159, + 0.04665905237197876, + -0.01630396395921707, + -0.020880484953522682, + -0.06532212346792221, + -0.003213261254131794, + 0.0416768379509449, + -0.05093088001012802, + -0.0871049091219902, + -0.014571009203791618, + 0.0010796786518767476, + 0.007087667006999254, + 0.05550219491124153, + -0.07753361761569977, + 0.022848013788461685, + 0.02596968039870262, + 0.04259824752807617, + -2.380165022444961e-33, + 0.05820159241557121, + 0.046025633811950684, + 0.10894608497619629, + 0.05244075506925583, + 0.15792003273963928, + 0.024086199700832367, + 0.029237573966383934, + -0.023072607815265656, + -0.07495220005512238, + -0.013094011694192886, + -0.004260784015059471, + -0.053080882877111435, + -0.00895928218960762, + -0.03149857744574547, + 0.13309381902217865, + 0.038643430918455124, + -0.02136029675602913, + -0.030247559770941734, + 0.08822915703058243, + -0.026076463982462883, + 0.050446517765522, + 0.011856893077492714, + -0.06957101821899414, + -0.02773614600300789, + 0.04625667631626129, + 0.008786994963884354, + -0.07701855897903442, + 0.001076446962542832, + -0.004858669359236956, + 0.0067254831083118916, + -0.02791707031428814, + -0.019495468586683273, + 0.0703381896018982, + 0.030558260157704353, + -0.05546342208981514, + 0.0420801043510437, + -0.03730127215385437, + -0.01322201732546091, + 0.038336288183927536, + 0.06427455693483353, + 0.028238974511623383, + -0.06713984161615372, + 0.03150900453329086, + 0.024600861594080925, + 0.016221575438976288, + 0.025838203728199005, + -0.02313261851668358, + 0.0557485967874527, + 0.015211678110063076, + 0.029895616695284843, + 0.06008606031537056, + 0.04473312199115753, + -0.050083715468645096, + -0.017571061849594116, + -0.014091495424509048, + -0.06641074270009995, + -0.008071008138358593, + 0.03312089666724205, + -0.09482058882713318, + -0.08763624727725983, + 0.030528157949447632, + 0.013274747878313065, + 0.06158939003944397, + 0.0748405009508133, + -0.12128522247076035, + -0.12076683342456818, + 0.0464591421186924, + 0.0045278542675077915, + -0.002574144396930933, + -0.028266169130802155, + -0.04953430965542793, + -0.007604515179991722, + -0.01084962673485279, + -0.06370151042938232, + 0.00812828354537487, + -0.027805447578430176, + 0.044624149799346924, + 0.016610005870461464, + -0.027103105559945107, + -0.046117331832647324, + -0.002852817066013813, + 0.05479831248521805, + 0.05342277139425278, + -0.03752776235342026, + -0.0053502353839576244, + -0.018950853496789932, + -0.07712738960981369, + -0.13029317557811737, + -0.013171681202948093, + 0.02069253847002983, + 0.029317859560251236, + 0.018668048083782196, + -0.061371881514787674, + 0.05376929044723511, + 0.01483837515115738, + -3.964297690117746e-08, + 0.03559036925435066, + -0.005289694294333458, + -0.013635152950882912, + -0.020672710612416267, + 0.039649732410907745, + -0.06206038221716881, + 0.04933065176010132, + 0.010378899984061718, + 0.020493512973189354, + 0.027486076578497887, + 0.07419533282518387, + -0.03473059833049774, + 0.05251400172710419, + 0.013588557951152325, + 0.01814397983253002, + -0.024619124829769135, + 0.11751414835453033, + 0.05483951419591904, + 0.022471528500318527, + 0.0301313828676939, + 0.018649602308869362, + -0.06219587102532387, + 0.04238469526171684, + -0.053293377161026, + 0.002427657600492239, + -0.0019911346025764942, + 0.004944113548845053, + -0.061433035880327225, + -0.013191037811338902, + -0.030179856345057487, + -0.051340680569410324, + 0.022094713523983955, + -0.035341646522283554, + -0.007219062652438879, + -0.06182244420051575, + -0.06059279292821884, + -0.041057273745536804, + 0.002089729532599449, + -0.043397895991802216, + 0.07170896232128143, + 0.036471735686063766, + -0.015439609996974468, + -0.01848314143717289, + 0.0056609525345265865, + -0.0012752920156344771, + -0.056571539491415024, + -0.01979043148458004, + -0.12011151015758514, + -0.02223217859864235, + 0.029830070212483406, + 0.027551136910915375, + -0.0010704555315896869, + 0.000702365068718791, + -0.005173679441213608, + -0.019360698759555817, + 0.17009279131889343, + -0.04601005092263222, + -0.04016156122088432, + -0.01600208878517151, + 0.04198170080780983, + 0.02032368630170822, + -0.06263051927089691, + -0.048464443534612656, + 0.009351130574941635 + ], + "model": "WattBike", + "pickup_zone": "POLYGON((2.1767 48.9016, 2.5267 48.9016, 2.5267 48.5516, 2.1767 48.5516, 2.1767 48.9016))", + "price": 2300, + "store_location": "2.3522,48.8566" + }, + { + "brand": "Peaknetic", + "condition": "new", + "description": "If you struggle with stiff fingers or a kinked neck or back after a few minutes on the road, this lightweight, aluminum bike alleviates those issues and allows you to enjoy the ride. From the ergonomic grips to the lumbar-supporting seat position, the Roll Low-Entry offers incredible comfort. The rear-inclined seat tube facilitates stability by allowing you to put a foot on the ground to balance at a stop, and the low step-over frame makes it accessible for all ability and mobility levels. The saddle is very soft, with a wide back to support your hip joints and a cutout in the center to redistribute that pressure. Rim brakes deliver satisfactory braking control, and the wide tires provide a smooth, stable ride on paved roads and gravel. Rack and fender mounts facilitate setting up the Roll Low-Entry as your preferred commuter, and the BMX-like handlebar offers space for mounting a flashlight, bell, or phone holder.", + "description_embeddings": [ + 0.0022135202307254076, + 0.0681997612118721, + 0.0064607178792357445, + 0.007070810534060001, + -0.054231829941272736, + 0.008059866726398468, + 0.040072083473205566, + 0.0956423208117485, + 0.049143481999635696, + 0.0379914790391922, + -0.020757146179676056, + 0.06460786610841751, + 0.07982552796602249, + -0.0321788415312767, + -0.006194670218974352, + 0.0375053696334362, + 0.1270381063222885, + -0.02341461181640625, + -0.007247396744787693, + 0.0682845488190651, + -0.026470346376299858, + 0.005658577661961317, + 0.04653697833418846, + 0.03987714648246765, + -0.12344618886709213, + 0.03188862279057503, + -0.02708076685667038, + 0.06964577734470367, + 0.02201199159026146, + -0.02890665829181671, + -0.040280576795339584, + 0.06318672746419907, + 0.07309666275978088, + -0.08932560682296753, + -0.11648543179035187, + -0.029937371611595154, + 0.10487373173236847, + 0.041655637323856354, + -0.022871389985084534, + -0.04677774757146835, + 0.02746077999472618, + 0.01847464218735695, + 0.08173345029354095, + 0.06561841815710068, + 0.05970228090882301, + -0.024480478838086128, + 0.06907600909471512, + -0.03947169706225395, + 0.024855393916368484, + -0.013199429027736187, + 0.09996063262224197, + 0.0028578736819326878, + 0.08506831526756287, + 0.014810853637754917, + -0.03929787874221802, + 0.0018542942125350237, + -0.14215077459812164, + 0.06970464438199997, + 0.0265016071498394, + -0.06698428839445114, + 0.07732488960027695, + -0.04583248123526573, + 0.028696633875370026, + 0.013155206106603146, + 0.02578958310186863, + -0.029291296377778053, + -0.00031816380214877427, + -0.125708669424057, + -0.042060736566782, + -0.05381627008318901, + -0.0538906455039978, + 0.0014778936747461557, + -0.09889215975999832, + -0.0429794080555439, + -0.013458915054798126, + -0.04558553919196129, + 0.09005370736122131, + -0.04213777929544449, + -0.1349189579486847, + 0.055852413177490234, + 0.006197084207087755, + 0.016338912770152092, + 0.032463233917951584, + 0.02548987604677677, + 0.030681701377034187, + -0.0703219398856163, + 0.05395807698369026, + -0.009628057479858398, + -0.031475286930799484, + -0.027579376474022865, + 0.04098684713244438, + 0.03901920095086098, + -0.01192146260291338, + -0.04101356491446495, + -0.08753280341625214, + 0.0705665871500969, + 0.03578994423151016, + 0.032069701701402664, + -0.03211764618754387, + 0.09590566158294678, + 0.0611797571182251, + 0.004700345452874899, + 0.10438291728496552, + 0.07409676164388657, + -0.0090691689401865, + 0.011407091282308102, + 0.05370165407657623, + -0.020438825711607933, + -0.04398776963353157, + 0.032895661890506744, + -0.0012730252929031849, + 0.018297234550118446, + -0.04333885386586189, + 0.06208101287484169, + -0.08955910801887512, + -0.04672509804368019, + -0.06376977264881134, + 0.022537674754858017, + 0.02881341427564621, + -0.0030273371376097202, + -0.06542699784040451, + 0.007231372408568859, + 0.01855703443288803, + 0.012365416623651981, + 0.018434280529618263, + -0.04855069890618324, + -0.08907819539308548, + -2.615521077916409e-34, + -0.046131156384944916, + -0.028526470065116882, + 0.01342072058469057, + -0.010418130084872246, + -0.019669201225042343, + -0.07430055737495422, + -0.006000629626214504, + -0.03320513665676117, + -0.05303066596388817, + 0.07680810242891312, + -0.0061429338529706, + 0.06154831871390343, + 0.09432042390108109, + 0.0038354273419827223, + 0.14506474137306213, + -0.07032876461744308, + -0.07443196326494217, + -0.04439792409539223, + -0.005104243289679289, + -3.3934433304239064e-05, + -0.08257872611284256, + -0.056131236255168915, + 0.04174238070845604, + 0.0017745267832651734, + -0.002772972686216235, + 0.006998051423579454, + 0.09371285885572433, + -0.013138788752257824, + -0.042773280292749405, + 0.00896062795072794, + -0.09441300481557846, + -0.007952050305902958, + -0.015586148016154766, + -0.017506571486592293, + 0.01347337942570448, + 0.027937229722738266, + -0.11657726019620895, + -0.03324989974498749, + -0.018427638337016106, + -0.04819897934794426, + -0.04077771306037903, + -0.0001697312545729801, + -0.05697356536984444, + 0.07191669940948486, + 0.017228955402970314, + 0.03711475431919098, + 0.042057864367961884, + 0.004786928184330463, + -0.06956200301647186, + 0.06036132574081421, + -0.0016305814497172832, + 0.02468821406364441, + -0.013794313184916973, + -0.025994934141635895, + -0.07489914447069168, + 0.01067660003900528, + -0.010298662818968296, + -0.022154971957206726, + -0.09746527671813965, + 0.06335768103599548, + -0.022728655487298965, + -0.0005628599901683629, + -0.04313022270798683, + -0.04123309254646301, + -0.08378659188747406, + 0.020546691492199898, + 0.01680913008749485, + -0.010155763477087021, + 0.008547178469598293, + -0.0211178008466959, + 0.023050235584378242, + 0.06479462236166, + 0.061528537422418594, + 0.022156352177262306, + 0.019619867205619812, + 0.07456795871257782, + 0.049971628934144974, + -0.07878398895263672, + 0.04972408711910248, + -0.015442566946148872, + 0.044758349657058716, + -0.037393294274806976, + -0.03831558674573898, + -0.016534404829144478, + -0.05692937225103378, + 0.02438316121697426, + -0.008604591712355614, + -0.06003899499773979, + 0.04884570837020874, + -0.05407913774251938, + -0.004864877089858055, + -0.039421387016773224, + -0.0335439033806324, + 0.05149518698453903, + -0.00761334178969264, + -4.919814414418271e-34, + 0.0605306513607502, + 0.013155259191989899, + 0.0022042335476726294, + -0.016238724812865257, + 0.017820321023464203, + -0.029504502192139626, + 0.1179562360048294, + -0.08494631201028824, + -0.05847567319869995, + -0.03412671759724617, + 0.01584434323012829, + 0.0205944012850523, + 0.011703073978424072, + 0.024820921942591667, + 0.07683313637971878, + 0.016703670844435692, + -0.0465223602950573, + -0.08929521590471268, + 0.013778958469629288, + -0.06448621302843094, + 0.047237128019332886, + 0.11140323430299759, + -0.036479681730270386, + -0.055252984166145325, + -0.08155377954244614, + -0.0011454259511083364, + -0.07414430379867554, + 0.04839516803622246, + -0.036127883940935135, + 0.04249665141105652, + -0.05564387887716293, + 0.008439254947006702, + 0.056384216994047165, + 0.0037136792670935392, + -0.06267311424016953, + 0.06599505990743637, + -0.0944608598947525, + -0.01900491677224636, + 0.0017078104428946972, + 0.018181079998612404, + 0.0072936019860208035, + 0.03901578113436699, + 0.022009696811437607, + -0.02042953297495842, + 0.04422936588525772, + 0.099826380610466, + 0.0022175773046910763, + 0.05569764971733093, + 0.005229232832789421, + -0.06281892955303192, + 0.06203164905309677, + 0.05493532121181488, + 0.06598878651857376, + 0.06272768974304199, + 0.05623844638466835, + -0.053184594959020615, + 0.012609804049134254, + -0.009191329590976238, + -0.07956400513648987, + -0.005095178727060556, + -0.06295286118984222, + 0.05799472704529762, + 0.004298996180295944, + -0.0245245061814785, + -0.010027579963207245, + -0.02338206022977829, + -0.03576310724020004, + -0.0735088586807251, + -0.10477573424577713, + 0.010318689979612827, + -0.031293049454689026, + -0.06913845986127853, + 0.07762496173381805, + -0.029345618560910225, + 0.03347797319293022, + 0.014305013231933117, + 0.06321006268262863, + -0.09872464835643768, + -0.040937263518571854, + 0.028350593522191048, + -0.08784928917884827, + 0.005375882610678673, + 0.059733789414167404, + 0.027322115376591682, + -0.04657347500324249, + 0.02783248759806156, + -0.12815773487091064, + 0.004414730705320835, + -0.009058866649866104, + 0.06062375009059906, + 0.04072198644280434, + 0.05082780495285988, + -0.036888547241687775, + 0.07301440089941025, + 0.022250277921557426, + -4.836826761334123e-08, + -0.02333931438624859, + -0.0006597689352929592, + -0.011001646518707275, + 0.01690472476184368, + -0.0037487675435841084, + 0.039681874215602875, + -0.012263616546988487, + 0.010128140449523926, + 0.03165998309850693, + 0.0028211181052029133, + 0.009292887523770332, + -0.05068610981106758, + -0.05350435897707939, + 0.0027450143825262785, + -0.02869512513279915, + 0.18523184955120087, + 0.010015024803578854, + 0.04042758792638779, + 0.010014397092163563, + -0.07638011872768402, + -0.04126984626054764, + -0.06051325798034668, + 0.04609273001551628, + -0.00863336119800806, + -0.010159372352063656, + -0.0686831921339035, + -0.022274712100625038, + 0.054596077650785446, + -0.004217579495161772, + 0.005010589957237244, + -0.0023027928546071053, + 0.054350487887859344, + 0.051168326288461685, + -0.0005977987311780453, + 0.0008231411338783801, + -0.005349422339349985, + -0.04023698344826698, + 0.01875622756779194, + 0.051792532205581665, + 0.0725129023194313, + 0.003990984987467527, + -0.0412585511803627, + -0.030975697562098503, + 0.02229507826268673, + -0.023536084219813347, + 0.004254089202731848, + -0.047596003860235214, + 0.054139409214258194, + 0.024750487878918648, + 0.00830126740038395, + 0.04204926639795303, + -0.05580601468682289, + 0.014396552927792072, + 0.0785103291273117, + -0.01755904220044613, + 0.09679318964481354, + -0.01722336746752262, + -0.03680667281150818, + -0.021823544055223465, + 0.044612541794776917, + -0.0008680447936058044, + 0.027066197246313095, + -0.008826435543596745, + -0.034606464207172394 + ], + "model": "Secto", + "pickup_zone": "POLYGON((13.3260 52.5700, 13.6550 52.5700, 13.6550 52.2700, 13.3260 52.2700, 13.3260 52.5700))", + "price": 430, + "store_location": "13.4050,52.5200" + }, + { + "brand": "nHill", + "condition": "new", + "description": "This budget mountain bike from nHill performs well both on bike paths and on the trail. The fork with 100mm of travel absorbs rough terrain. Fat Kenda Booster tires give you grip in corners and on wet trails. The Shimano Tourney drivetrain offered enough gears for finding a comfortable pace to ride uphill, and the Tektro hydraulic disc brakes break smoothly. Whether you want an affordable bike that you can take to work, but also take trail in mountains on the weekends or you\u2019re just after a stable, comfortable ride for the bike path, the Summit gives a good value for money.", + "description_embeddings": [ + -0.024333441630005836, + 0.029308300465345383, + -0.012847754172980785, + -0.013123984448611736, + -0.039905961602926254, + -0.04596070945262909, + -0.01287133153527975, + 0.03984961286187172, + -0.043438445776700974, + 0.012349214404821396, + -0.021342391148209572, + -0.027458613738417625, + -0.004793129395693541, + 0.016479987651109695, + 0.02052542380988598, + -0.009542089886963367, + 0.10066469013690948, + 0.017397526651620865, + 0.07893014699220657, + -0.0765308141708374, + -0.007650941610336304, + 9.538845188217238e-05, + 0.03314477205276489, + 0.026631362736225128, + -0.01621824875473976, + 0.03593063727021217, + -0.014871303923428059, + 0.05259871482849121, + 0.027785824611783028, + -0.044416770339012146, + -0.026691904291510582, + -0.01390022411942482, + -0.0573929138481617, + -0.08761026710271835, + 0.012642575427889824, + 0.04252056032419205, + 0.04015251249074936, + -0.0052475095726549625, + -0.08608037978410721, + 0.0028531427960842848, + -0.003371630096808076, + -0.02032443881034851, + -0.029511747881770134, + -0.043690912425518036, + 0.042122989892959595, + -0.057133886963129044, + 0.019293654710054398, + -0.019127611070871353, + 0.036713697016239166, + -0.00833116751164198, + 0.009040397591888905, + -0.1087319627404213, + 0.09127230197191238, + -0.048213958740234375, + -0.023604029789566994, + 0.0008899428648874164, + -0.093184694647789, + -0.03436879441142082, + 0.00807907897979021, + -0.0520450733602047, + 0.02262270636856556, + -0.03259866312146187, + -0.0391012541949749, + 0.001295328140258789, + 0.06636986881494522, + -0.04248524457216263, + -0.07093628495931625, + -0.06715728342533112, + 0.007415436673909426, + -0.06185786426067352, + 0.036563266068696976, + 0.030749274417757988, + 0.007705106865614653, + 0.0023627770133316517, + -0.026215652003884315, + -0.020864665508270264, + 0.05270038917660713, + 0.021477004513144493, + 0.0068344962783157825, + 0.024355463683605194, + -0.03746088594198227, + 0.031043346971273422, + 0.09879995882511139, + -0.050035204738378525, + 0.08045479655265808, + -0.04274336248636246, + 0.02994127944111824, + -0.03783947601914406, + 0.039749279618263245, + 0.046901557594537735, + 0.08667739480733871, + 0.02831847593188286, + -0.008148318156599998, + 0.007401767186820507, + -0.10989774018526077, + -0.014092149212956429, + 9.036048140842468e-06, + 0.054770372807979584, + -0.012413500808179379, + 0.01861056312918663, + 0.060349978506565094, + 0.06291640549898148, + 0.007055714726448059, + -0.021361181512475014, + 0.03852728381752968, + -0.018908292055130005, + 0.047424111515283585, + 0.054501011967659, + 0.017648596316576004, + 0.11429999768733978, + -0.041358742862939835, + -0.03363256901502609, + 0.0030338421929627657, + 0.030056871473789215, + 0.008060693740844727, + -0.0688784271478653, + -0.09984277933835983, + 0.030267179012298584, + -0.028509166091680527, + 0.02268315851688385, + -0.07580948621034622, + -0.0405895970761776, + 0.03384138271212578, + 0.07081738114356995, + 0.019772004336118698, + -0.06172173097729683, + 0.008248022757470608, + 1.9840379362262432e-33, + 0.037930894643068314, + 0.04577890411019325, + -0.03732670471072197, + -0.032416991889476776, + 0.014588817022740841, + -0.06602118909358978, + -0.013814577832818031, + -0.10539791733026505, + -0.12850415706634521, + -0.005076196976006031, + -0.07302963733673096, + 0.07235066592693329, + -0.04646436870098114, + 0.059371400624513626, + 0.09111672639846802, + -0.10133209824562073, + -0.05483068525791168, + -0.053797587752342224, + -0.03709062561392784, + 0.08241501450538635, + 0.03958267718553543, + 0.01433452870696783, + 0.05912068858742714, + -0.0029660870786756277, + 0.01806815154850483, + -0.0680701732635498, + 0.013625666499137878, + 0.015582672320306301, + -0.02142208069562912, + 0.06357447057962418, + -0.12094264477491379, + -0.09666852653026581, + -0.03333089128136635, + -0.06621623784303665, + -0.03821765258908272, + -0.010776739567518234, + -0.08198492974042892, + -0.03277386352419853, + 0.014794036746025085, + 0.013517632149159908, + -0.0034003634937107563, + 0.005664682947099209, + -0.022207774221897125, + 0.015086682513356209, + -0.06799489259719849, + 0.08191754668951035, + 0.15600024163722992, + 0.07579171657562256, + -0.05843832343816757, + -0.008412746712565422, + -0.07857701182365417, + -0.0038521387614309788, + -0.02901686355471611, + 0.0006679021753370762, + -0.0697081908583641, + -0.05330892279744148, + 0.053166620433330536, + 0.004783661104738712, + 0.013741954229772091, + 0.07203977555036545, + -0.015861764550209045, + 0.033332549035549164, + -0.022547632455825806, + -0.011850795708596706, + -0.09526507556438446, + -0.016078950837254524, + -0.004922114312648773, + 0.004731250926852226, + -0.006536174099892378, + 0.004852978512644768, + 0.01268527377396822, + 0.05300697684288025, + 0.11899229139089584, + 0.025274425745010376, + 0.11763036996126175, + -0.08781222999095917, + -0.016429787501692772, + -0.02661072462797165, + -0.01769474893808365, + 0.05961911380290985, + 0.005877051502466202, + -0.03780582174658775, + -0.028037618845701218, + 0.023397648707032204, + -0.006716609466820955, + 0.015020519495010376, + 0.040884219110012054, + -0.06197969987988472, + -0.029691174626350403, + -0.004976964555680752, + -0.03422437235713005, + 0.018984060734510422, + -0.00813105795532465, + -0.020747167989611626, + 0.0281930360943079, + -3.2326105667872445e-33, + 0.12847235798835754, + 0.026267321780323982, + 0.10983140766620636, + 0.011159190908074379, + -0.044980239123106, + 0.017553674057126045, + -0.004794386215507984, + -0.015802551060914993, + -0.01226617582142353, + -0.019019361585378647, + 0.011876302771270275, + -0.023136194795370102, + 0.03209578990936279, + 0.07442695647478104, + 0.05641649663448334, + -0.05300089344382286, + -0.03638714924454689, + -0.014843880198895931, + 0.036886364221572876, + -0.1257546991109848, + -0.008151554502546787, + 0.07542898505926132, + -0.11252967268228531, + -0.09049033373594284, + -0.0030374047346413136, + 0.04011000320315361, + -0.1538117229938507, + 0.07717141509056091, + -0.04436258599162102, + 0.07290291786193848, + -0.0072043901309370995, + 0.03950807452201843, + 0.002569766016677022, + -0.006248284596949816, + 0.001176450401544571, + 0.12515375018119812, + 0.02005600742995739, + -0.00013864059292245656, + 0.024221621453762054, + 0.05465780198574066, + 0.09940708428621292, + -0.053944025188684464, + 0.09602796286344528, + 0.00014552564243786037, + 0.026602625846862793, + 0.016811460256576538, + 0.0015170868718996644, + 0.08731727302074432, + 0.005771235562860966, + -0.009904555976390839, + 0.06958170980215073, + 0.09265917539596558, + 0.005830116104334593, + 0.10210693627595901, + 0.0011325017549097538, + -0.006749417632818222, + 0.01503710262477398, + -0.03714510798454285, + -0.0939728170633316, + -0.03357759863138199, + -0.050196800380945206, + -0.006316252052783966, + -0.06414957344532013, + 0.007235861383378506, + -0.01670873910188675, + -0.07423098385334015, + 0.018221961334347725, + -0.05320512503385544, + -0.010248126462101936, + 0.013013344258069992, + -0.12916545569896698, + -0.04244375228881836, + 0.08774643391370773, + -0.03917357325553894, + -0.027767449617385864, + 0.02099072001874447, + 0.0595061257481575, + 0.01945589855313301, + 0.03815269470214844, + -0.028747402131557465, + -0.025533201172947884, + -0.038349006325006485, + -0.014486055821180344, + -0.013576257973909378, + 0.051731329411268234, + 0.06515145301818848, + -0.011720783077180386, + -0.1163521260023117, + -0.03931708261370659, + 0.03394515439867973, + 0.09380073100328445, + 0.00931628793478012, + -0.01171857863664627, + 0.04104544222354889, + -0.008916886523365974, + -4.140364140425845e-08, + 0.061763226985931396, + 0.02101300284266472, + -0.019075985997915268, + -0.002017116406932473, + 0.015830116346478462, + -0.009857675060629845, + -0.018932191655039787, + -0.0007055550813674927, + 0.013249439187347889, + 0.0642324835062027, + 0.12860508263111115, + 0.03213700279593468, + -0.0670522004365921, + 0.041800037026405334, + -0.0426088348031044, + 0.0437115803360939, + 0.021514814347028732, + 0.12901803851127625, + 0.015236952342092991, + -0.02232329733669758, + -0.05031055584549904, + -0.052778035402297974, + 0.000233030179515481, + -0.022497626021504402, + -0.014370465651154518, + 0.017518600448966026, + 0.014312495477497578, + 0.010902844369411469, + 0.0027771666646003723, + -0.04195915535092354, + -0.06504479050636292, + 0.038553908467292786, + -0.01374481339007616, + 0.03843652829527855, + 0.09058628976345062, + -0.0230315700173378, + -0.11761228740215302, + 0.06487669050693512, + -0.005885662976652384, + 0.06288695335388184, + 0.05191958323121071, + 0.011840583756566048, + -0.027309859171509743, + 0.040654800832271576, + -0.005980184301733971, + 0.03252403438091278, + -0.043744225054979324, + 0.006068602204322815, + -0.00032751375692896545, + -0.022902367636561394, + -0.050694938749074936, + 0.026743048802018166, + 0.06005466729402542, + 0.02092430181801319, + 0.02072584442794323, + 0.08342021703720093, + -0.05768749862909317, + -0.08585236966609955, + -0.03160274401307106, + 0.05222279205918312, + 0.029474787414073944, + -0.08763033896684647, + -0.01591801643371582, + -0.07798203080892563 + ], + "model": "Summit", + "pickup_zone": "POLYGON((1.9450 41.4301, 2.4018 41.4301, 2.4018 41.1987, 1.9450 41.1987, 1.9450 41.4301))", + "price": 1200, + "store_location": "2.1734, 41.3851" + }, + { + "brand": "BikeShind", + "condition": "refurbished", + "description": "An artsy, retro-inspired bicycle that\u2019s as functional as it is pretty: The ThrillCycle steel frame offers a smooth ride. A 9-speed drivetrain has enough gears for coasting in the city, but we wouldn\u2019t suggest taking it to the mountains. Fenders protect you from mud, and a rear basket lets you transport groceries, flowers and books. The ThrillCycle comes with a limited lifetime warranty, so this little guy will last you long past graduation.", + "description_embeddings": [ + -0.005154624115675688, + 0.10099548101425171, + 0.04890008643269539, + 0.0625317171216011, + -0.0363173745572567, + 0.025850096717476845, + 0.032137978821992874, + -0.03442877531051636, + -0.10096120089292526, + -0.007441149093210697, + 0.002616145182400942, + 0.002316742204129696, + 0.042584337294101715, + 0.026208963245153427, + 0.018415318801999092, + 0.050033390522003174, + 0.14831797778606415, + -0.006160213612020016, + 0.05086936056613922, + 0.0131875304505229, + -0.05973455682396889, + 0.045886117964982986, + -0.025052331387996674, + 0.04576171189546585, + -0.006168896332383156, + 0.03315199911594391, + -0.07763667404651642, + 0.05837876722216606, + -0.03229084238409996, + -0.021293187513947487, + -0.008595496416091919, + 0.06880632787942886, + -0.04528025537729263, + -0.020664094015955925, + -0.029125794768333435, + 0.0445701889693737, + 0.023799002170562744, + -0.013527574017643929, + -0.01646343804895878, + 0.027023920789361, + 0.0014843698590993881, + 0.014952401630580425, + -0.010172702372074127, + 0.07603776454925537, + 0.017975280061364174, + -0.08911248296499252, + 0.055482957512140274, + -0.027819648385047913, + 0.019395964220166206, + 0.05424710363149643, + 0.06634850054979324, + -0.05045575276017189, + -0.0006240577204152942, + -0.06339468061923981, + -0.023632608354091644, + -0.060364823788404465, + -0.11193189769983292, + 0.046562716364860535, + -0.010353066958487034, + -0.043506212532520294, + 0.051063187420368195, + 0.003231980837881565, + 0.027102531865239143, + 0.002380193443968892, + -0.0056939758360385895, + -0.026826998218894005, + -0.014482468366622925, + -0.0185822993516922, + 0.013927196152508259, + -0.10704471915960312, + 0.0673733651638031, + -0.0010599792003631592, + -0.07455477863550186, + -0.014452059753239155, + -0.02294282428920269, + -0.010201872326433659, + 0.023037923499941826, + -0.05595972761511803, + -0.09120096266269684, + -0.029177049174904823, + -0.02343042939901352, + -0.029726101085543633, + 0.07366959005594254, + -0.046458736062049866, + 0.006261167582124472, + -0.013148028403520584, + -0.0014217026764526963, + 0.017440352588891983, + -0.04511420056223869, + 0.008813070133328438, + -0.022654451429843903, + -0.014097515493631363, + -0.020799456164240837, + -0.05456947907805443, + -0.07338607311248779, + 0.017073828727006912, + -0.04925030097365379, + -0.024428002536296844, + -0.00979585014283657, + 0.025696750730276108, + 0.07033320516347885, + 0.0389082096517086, + 0.12711860239505768, + 0.07472020387649536, + -0.019501805305480957, + 0.01663217693567276, + 0.027799105271697044, + 0.039703886955976486, + -0.029871169477701187, + 0.005997804459184408, + -0.0015701024094596505, + 0.0411832258105278, + 8.85713889147155e-05, + -0.029442811384797096, + 0.009789851494133472, + -0.04723270237445831, + -0.09891993552446365, + 0.05102938041090965, + -0.007144609931856394, + 0.01668076030910015, + 0.004902719985693693, + 0.02218448370695114, + 0.03827798366546631, + 0.001542922342196107, + 0.004610520787537098, + -0.12595036625862122, + 0.07361572980880737, + -1.521196586481568e-33, + -0.01484542153775692, + 0.024973904713988304, + 0.006633534096181393, + 0.01254032738506794, + 0.06355929374694824, + -0.04809075966477394, + 0.02005922608077526, + -0.06251886487007141, + -0.06941430270671844, + 0.02304103970527649, + -0.020975833758711815, + 0.08137834072113037, + 0.049319952726364136, + 0.11945393681526184, + 0.17472721636295319, + -0.03430051729083061, + -0.07276412844657898, + -0.11828659474849701, + 0.04918891564011574, + -0.07279565185308456, + -0.06228293105959892, + -0.03494764119386673, + 0.004517378751188517, + -0.0431801863014698, + -0.07457974553108215, + -0.0003888327337335795, + 0.05853814631700516, + 0.05362739413976669, + 0.01866878569126129, + 0.004751134198158979, + -0.07936650514602661, + 0.033309247344732285, + -0.01660560630261898, + -0.08851712942123413, + 0.042956508696079254, + 0.03460550308227539, + -0.054352447390556335, + -0.016094308346509933, + 0.019760286435484886, + -0.03591147065162659, + -0.04307156056165695, + -0.04029138758778572, + -0.09315019100904465, + 0.055713504552841187, + 0.003642909461632371, + 0.0391569547355175, + 0.1300928145647049, + 0.026774607598781586, + -0.054334208369255066, + -0.060861144214868546, + -0.020662454888224602, + -0.034525640308856964, + 0.004193050786852837, + 0.02453654631972313, + -0.09028972685337067, + 0.004444751888513565, + 0.06320545822381973, + 0.01895289309322834, + -0.04660886526107788, + 0.08611723780632019, + 0.05705415457487106, + 0.030612647533416748, + 0.019753821194171906, + -0.061483170837163925, + -0.025262145325541496, + 0.054222241044044495, + 0.017605014145374298, + -0.013110420666635036, + 0.04744894057512283, + -0.004785404074937105, + 0.04680679365992546, + 0.001831064117141068, + 0.07773134112358093, + 0.008347200229763985, + 0.08674833923578262, + 0.024294976145029068, + -0.03695613518357277, + -0.0440739244222641, + 0.00895663257688284, + -0.0060102143324911594, + -0.0361272394657135, + -0.08447428047657013, + -0.08971717208623886, + 0.03131894767284393, + 0.0721370130777359, + 0.031180810183286667, + 0.039390258491039276, + -0.09044987708330154, + -0.007888346910476685, + 0.008131768554449081, + -0.03624662756919861, + -0.033649034798145294, + 0.031620997935533524, + 0.05870470404624939, + 0.018141048029065132, + -5.7662626416839565e-34, + 0.09117024391889572, + -0.023953478783369064, + 0.080879345536232, + 0.0035459804348647594, + -0.013222851790487766, + -0.025237491354346275, + 0.019038159400224686, + -0.06588941067457199, + -0.11689981818199158, + 0.0007165187271311879, + -0.0933104082942009, + 0.014618181623518467, + 0.12644915282726288, + 0.0027253602165728807, + 0.15038658678531647, + 0.0053163510747253895, + -0.005645217839628458, + 0.009321562945842743, + 0.002719732467085123, + -0.01651378907263279, + 0.0063886744901537895, + 0.05738385394215584, + -0.14213474094867706, + -0.0669025406241417, + -0.05766160413622856, + 0.0031909833196550608, + -0.13478563725948334, + -0.03741385415196419, + 0.041654907166957855, + 0.04030514881014824, + -0.05102578178048134, + 0.0028968513943254948, + 0.0738285705447197, + -0.03643025830388069, + -0.015445208176970482, + 0.06674294173717499, + 0.029759766533970833, + -0.024196317419409752, + -0.009355752728879452, + 0.023269686847925186, + 0.01623220555484295, + -0.08251868188381195, + 0.020170293748378754, + 0.0749305933713913, + 0.08206077665090561, + 0.012237507849931717, + -0.026570556685328484, + 0.016253553330898285, + -0.003425935748964548, + 0.005059909541159868, + 0.12109038233757019, + 0.08107315003871918, + -0.04097432270646095, + 0.0009462210582569242, + 0.058092083781957626, + -0.03609737753868103, + -0.01580999232828617, + -0.0342475026845932, + 0.012185491621494293, + -0.058348096907138824, + -0.05934947729110718, + 0.026715252548456192, + -0.031246516853570938, + 0.012632215395569801, + -0.01100403256714344, + -0.05962579324841499, + -0.000801989808678627, + -0.06919746845960617, + -0.1299775391817093, + -0.03721063956618309, + -0.03989635780453682, + 0.04918158799409866, + -0.0022671804763376713, + -0.04244564101099968, + -0.02631748840212822, + -0.04100838303565979, + 0.08634430915117264, + 0.05031242221593857, + 0.06688959896564484, + 0.024407675489783287, + 0.0018788984743878245, + -0.026026425883173943, + 0.04438408091664314, + 0.02198263816535473, + -0.014974343590438366, + -0.026490231975913048, + -0.09914876520633698, + -0.09834708273410797, + 0.017346272245049477, + 0.00089951854897663, + 0.05497178062796593, + 0.06180766969919205, + -0.050425756722688675, + 0.013637324795126915, + -0.03599657490849495, + -4.404103037813911e-08, + -0.0024933917447924614, + 0.049585312604904175, + -0.020710783079266548, + -0.014283453114330769, + -0.0064896950498223305, + 0.04579087719321251, + 0.02242390066385269, + 0.02515084482729435, + -0.031156959012150764, + 0.006718308199197054, + 0.061417631804943085, + -0.009935885667800903, + -0.021248064935207367, + 0.011152776889503002, + -0.059073783457279205, + 0.05840323865413666, + 0.06523993611335754, + 0.03690555691719055, + 0.03174441307783127, + 0.02336188219487667, + 0.003073832020163536, + -0.017117813229560852, + 0.02877660095691681, + 0.0017827276606112719, + -0.07995487004518509, + -0.032443612813949585, + -0.01474942360073328, + -0.016080526635050774, + 0.0771399736404419, + 0.017354682087898254, + -0.02578366920351982, + 0.004991421941667795, + 0.006590475793927908, + -0.032372940331697464, + 0.038421064615249634, + -0.1204696074128151, + -0.05457846075296402, + 0.036750562489032745, + 0.013932188041508198, + 0.0031626380514353514, + 0.009978784248232841, + -0.0138266421854496, + 0.006769631989300251, + 0.059896957129240036, + 0.00822784099727869, + -0.05025117099285126, + -0.10305225104093552, + -0.07187453657388687, + 0.00836241990327835, + 0.049537766724824905, + 0.007570290472358465, + -0.08729138970375061, + -0.020592620596289635, + 0.04918212443590164, + 0.054685790091753006, + 0.04091939702630043, + -0.05420788377523422, + -0.04473182559013367, + -0.11178043484687805, + 0.09808126091957092, + -0.015394269488751888, + -0.0039725536480546, + 0.03283742815256119, + -0.05677533522248268 + ], + "model": "ThrillCycle", + "pickup_zone": "POLYGON((12.4464 42.1028, 12.5464 42.1028, 12.5464 41.7028, 12.4464 41.7028, 12.4464 42.1028))", + "price": 815, + "store_location": "12.4964,41.9028" + } +] \ No newline at end of file diff --git a/doctests/dt-bitfield.js b/doctests/dt-bitfield.js new file mode 100644 index 00000000000..9685372de41 --- /dev/null +++ b/doctests/dt-bitfield.js @@ -0,0 +1,76 @@ +// EXAMPLE: bitfield_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END + +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START bf +let res1 = await client.bitField("bike:1:stats", [{ + operation: 'SET', + encoding: 'u32', + offset: '#0', + value: 1000 +}]); +console.log(res1); // >>> [0] + +let res2 = await client.bitField('bike:1:stats', [ + { + operation: 'INCRBY', + encoding: 'u32', + offset: '#0', + increment: -50 + }, + { + operation: 'INCRBY', + encoding: 'u32', + offset: '#1', + increment: 1 + } +]); +console.log(res2); // >>> [950, 1] + +let res3 = await client.bitField('bike:1:stats', [ + { + operation: 'INCRBY', + encoding: 'u32', + offset: '#0', + increment: 500 + }, + { + operation: 'INCRBY', + encoding: 'u32', + offset: '#1', + increment: 1 + } +]); +console.log(res3); // >>> [1450, 2] + +let res4 = await client.bitField('bike:1:stats', [ + { + operation: 'GET', + encoding: 'u32', + offset: '#0' + }, + { + operation: 'GET', + encoding: 'u32', + offset: '#1' + } +]); +console.log(res4); // >>> [1450, 2] +// STEP_END + +// REMOVE_START +assert.deepEqual(res1, [0]) +assert.deepEqual(res2, [950, 1]) +assert.deepEqual(res3, [1450, 2]) +assert.deepEqual(res4, [1450, 2]) +await client.close(); +// REMOVE_END diff --git a/doctests/dt-bitmap.js b/doctests/dt-bitmap.js new file mode 100644 index 00000000000..845fd2a721c --- /dev/null +++ b/doctests/dt-bitmap.js @@ -0,0 +1,39 @@ +// EXAMPLE: bitmap_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END + +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START ping +const res1 = await client.setBit("pings:2024-01-01-00:00", 123, 1) +console.log(res1) // >>> 0 + +const res2 = await client.getBit("pings:2024-01-01-00:00", 123) +console.log(res2) // >>> 1 + +const res3 = await client.getBit("pings:2024-01-01-00:00", 456) +console.log(res3) // >>> 0 +// STEP_END + +// REMOVE_START +assert.equal(res1, 0) +// REMOVE_END + +// STEP_START bitcount +// HIDE_START +await client.setBit("pings:2024-01-01-00:00", 123, 1) +// HIDE_END +const res4 = await client.bitCount("pings:2024-01-01-00:00") +console.log(res4) // >>> 1 +// STEP_END +// REMOVE_START +assert.equal(res4, 1) +await client.close(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/dt-bloom.js b/doctests/dt-bloom.js new file mode 100644 index 00000000000..d065937e763 --- /dev/null +++ b/doctests/dt-bloom.js @@ -0,0 +1,46 @@ +// EXAMPLE: bf_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END + +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START bloom +const res1 = await client.bf.reserve('bikes:models', 0.01, 1000); +console.log(res1); // >>> OK + +const res2 = await client.bf.add('bikes:models', 'Smoky Mountain Striker'); +console.log(res2); // >>> true + +const res3 = await client.bf.exists('bikes:models', 'Smoky Mountain Striker'); +console.log(res3); // >>> true + +const res4 = await client.bf.mAdd('bikes:models', [ + 'Rocky Mountain Racer', + 'Cloudy City Cruiser', + 'Windy City Wippet' +]); +console.log(res4); // >>> [true, true, true] + +const res5 = await client.bf.mExists('bikes:models', [ + 'Rocky Mountain Racer', + 'Cloudy City Cruiser', + 'Windy City Wippet' +]); +console.log(res5); // >>> [true, true, true] +// STEP_END + +// REMOVE_START +assert.equal(res1, 'OK') +assert.equal(res2, true) +assert.equal(res3, true) +assert.deepEqual(res4, [true, true, true]) +assert.deepEqual(res5, [true, true, true]) +await client.close(); +// REMOVE_END diff --git a/doctests/dt-cms.js b/doctests/dt-cms.js new file mode 100644 index 00000000000..b0d9fa68469 --- /dev/null +++ b/doctests/dt-cms.js @@ -0,0 +1,50 @@ +// EXAMPLE: cms_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END + +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START cms +const res1 = await client.cms.initByProb('bikes:profit', 0.001, 0.002); +console.log(res1); // >>> OK + +const res2 = await client.cms.incrBy('bikes:profit', { + item: 'Smoky Mountain Striker', + incrementBy: 100 +}); +console.log(res2); // >>> [100] + +const res3 = await client.cms.incrBy('bikes:profit', [ + { + item: 'Rocky Mountain Racer', + incrementBy: 200 + }, + { + item: 'Cloudy City Cruiser', + incrementBy: 150 + } +]); +console.log(res3); // >>> [200, 150] + +const res4 = await client.cms.query('bikes:profit', 'Smoky Mountain Striker'); +console.log(res4); // >>> [100] + +const res5 = await client.cms.info('bikes:profit'); +console.log(res5.width, res5.depth, res5.count); // >>> 2000 9 450 +// STEP_END + +// REMOVE_START +assert.equal(res1, 'OK') +assert.deepEqual(res2, [100]) +assert.deepEqual(res3, [200, 150]) +assert.deepEqual(res4, [100]) +assert.deepEqual(res5, { width: 2000, depth: 9, count: 450 }) +await client.close(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/dt-cuckoo.js b/doctests/dt-cuckoo.js new file mode 100644 index 00000000000..4b11bca2345 --- /dev/null +++ b/doctests/dt-cuckoo.js @@ -0,0 +1,38 @@ +// EXAMPLE: cuckoo_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END + +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START cuckoo +const res1 = await client.cf.reserve('bikes:models', 1000000); +console.log(res1); // >>> OK + +const res2 = await client.cf.add('bikes:models', 'Smoky Mountain Striker'); +console.log(res2); // >>> true + +const res3 = await client.cf.exists('bikes:models', 'Smoky Mountain Striker'); +console.log(res3); // >>> true + +const res4 = await client.cf.exists('bikes:models', 'Terrible Bike Name'); +console.log(res4); // >>> false + +const res5 = await client.cf.del('bikes:models', 'Smoky Mountain Striker'); +console.log(res5); // >>> true +// STEP_END + +// REMOVE_START +assert.equal(res1, 'OK') +assert.equal(res2, true) +assert.equal(res3, true) +assert.equal(res4, false) +assert.equal(res5, true) +await client.close(); +// REMOVE_END diff --git a/doctests/dt-geo.js b/doctests/dt-geo.js new file mode 100644 index 00000000000..7ec9376a8a7 --- /dev/null +++ b/doctests/dt-geo.js @@ -0,0 +1,59 @@ +// EXAMPLE: geo_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END + +// REMOVE_START +await client.del('bikes:rentable') +// REMOVE_END + +// STEP_START geoAdd +const res1 = await client.geoAdd('bikes:rentable', { + longitude: -122.27652, + latitude: 37.805186, + member: 'station:1' +}); +console.log(res1) // 1 + +const res2 = await client.geoAdd('bikes:rentable', { + longitude: -122.2674626, + latitude: 37.8062344, + member: 'station:2' +}); +console.log(res2) // 1 + +const res3 = await client.geoAdd('bikes:rentable', { + longitude: -122.2469854, + latitude: 37.8104049, + member: 'station:3' +}) +console.log(res3) // 1 +// STEP_END + +// REMOVE_START +assert.equal(res1, 1); +assert.equal(res2, 1); +assert.equal(res3, 1); +// REMOVE_END + +// STEP_START geoSearch +const res4 = await client.geoSearch( + 'bikes:rentable', { + longitude: -122.27652, + latitude: 37.805186, + }, + { radius: 5, + unit: 'km' + } +); +console.log(res4) // ['station:1', 'station:2', 'station:3'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res4, ['station:1', 'station:2', 'station:3']); +// REMOVE_END +await client.close() diff --git a/doctests/dt-hash.js b/doctests/dt-hash.js new file mode 100644 index 00000000000..e77d6fd7b95 --- /dev/null +++ b/doctests/dt-hash.js @@ -0,0 +1,98 @@ +// EXAMPLE: hash_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END +// STEP_START set_get_all +const res1 = await client.hSet( + 'bike:1', + { + 'model': 'Deimos', + 'brand': 'Ergonom', + 'type': 'Enduro bikes', + 'price': 4972, + } +) +console.log(res1) // 4 + +const res2 = await client.hGet('bike:1', 'model') +console.log(res2) // 'Deimos' + +const res3 = await client.hGet('bike:1', 'price') +console.log(res3) // '4972' + +const res4 = await client.hGetAll('bike:1') +console.log(res4) +/* +{ + brand: 'Ergonom', + model: 'Deimos', + price: '4972', + type: 'Enduro bikes' +} +*/ +// STEP_END + +// REMOVE_START +assert.equal(res1, 4); +assert.equal(res2, 'Deimos'); +assert.equal(res3, '4972'); +assert.deepEqual(res4, { + model: 'Deimos', + brand: 'Ergonom', + type: 'Enduro bikes', + price: '4972' +}); +// REMOVE_END + +// STEP_START hmGet +const res5 = await client.hmGet('bike:1', ['model', 'price']) +console.log(res5) // ['Deimos', '4972'] +// STEP_END + +// REMOVE_START +assert.deepEqual(Object.values(res5), ['Deimos', '4972']) +// REMOVE_END + +// STEP_START hIncrBy +const res6 = await client.hIncrBy('bike:1', 'price', 100) +console.log(res6) // 5072 +const res7 = await client.hIncrBy('bike:1', 'price', -100) +console.log(res7) // 4972 +// STEP_END + +// REMOVE_START +assert.equal(res6, 5072) +assert.equal(res7, 4972) +// REMOVE_END + +// STEP_START hIncrBy_hGet_hMget +const res11 = await client.hIncrBy('bike:1:stats', 'rides', 1) +console.log(res11) // 1 +const res12 = await client.hIncrBy('bike:1:stats', 'rides', 1) +console.log(res12) // 2 +const res13 = await client.hIncrBy('bike:1:stats', 'rides', 1) +console.log(res13) // 3 +const res14 = await client.hIncrBy('bike:1:stats', 'crashes', 1) +console.log(res14) // 1 +const res15 = await client.hIncrBy('bike:1:stats', 'owners', 1) +console.log(res15) // 1 +const res16 = await client.hGet('bike:1:stats', 'rides') +console.log(res16) // 3 +const res17 = await client.hmGet('bike:1:stats', ['crashes', 'owners']) +console.log(res17) // ['1', '1'] +// STEP_END + +// REMOVE_START +assert.equal(res11, 1); +assert.equal(res12, 2); +assert.equal(res13, 3); +assert.equal(res14, 1); +assert.equal(res15, 1); +assert.equal(res16, '3'); +assert.deepEqual(res17, ['1', '1']); +await client.close(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/dt-hll.js b/doctests/dt-hll.js new file mode 100644 index 00000000000..762ce5db15e --- /dev/null +++ b/doctests/dt-hll.js @@ -0,0 +1,38 @@ +// EXAMPLE: hll_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END + +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START pfadd +const res1 = await client.pfAdd('bikes', ['Hyperion', 'Deimos', 'Phoebe', 'Quaoar']); +console.log(res1); // >>> 1 + +const res2 = await client.pfCount('bikes'); +console.log(res2); // >>> 4 + +const res3 = await client.pfAdd('commuter_bikes', ['Salacia', 'Mimas', 'Quaoar']); +console.log(res3); // >>> 1 + +const res4 = await client.pfMerge('all_bikes', ['bikes', 'commuter_bikes']); +console.log(res4); // >>> OK + +const res5 = await client.pfCount('all_bikes'); +console.log(res5); // >>> 6 +// STEP_END + +// REMOVE_START +assert.equal(res1, 1) +assert.equal(res2, 4) +assert.equal(res3, 1) +assert.equal(res4, 'OK') +assert.equal(res5, 6) +await client.close(); +// REMOVE_END diff --git a/doctests/dt-json.js b/doctests/dt-json.js new file mode 100644 index 00000000000..00578f48f33 --- /dev/null +++ b/doctests/dt-json.js @@ -0,0 +1,425 @@ +// EXAMPLE: json_tutorial +// HIDE_START +import assert from 'assert'; +import { + createClient +} from 'redis'; + +const client = await createClient(); +await client.connect(); +// HIDE_END +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START set_get +const res1 = await client.json.set("bike", "$", '"Hyperion"'); +console.log(res1); // OK + +const res2 = await client.json.get("bike", { path: "$" }); +console.log(res2); // ['"Hyperion"'] + +const res3 = await client.json.type("bike", { path: "$" }); +console.log(res3); // [ 'string' ] +// STEP_END + +// REMOVE_START +assert.deepEqual(res2, ['"Hyperion"']); +// REMOVE_END + +// STEP_START str +const res4 = await client.json.strLen("bike", { path: "$" }); +console.log(res4) // [10] + +const res5 = await client.json.strAppend("bike", '" (Enduro bikes)"'); +console.log(res5) // 27 + +const res6 = await client.json.get("bike", { path: "$" }); +console.log(res6) // ['"Hyperion"" (Enduro bikes)"'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res6, ['"Hyperion"" (Enduro bikes)"']); +// REMOVE_END + +// STEP_START num +const res7 = await client.json.set("crashes", "$", 0); +console.log(res7) // OK + +const res8 = await client.json.numIncrBy("crashes", "$", 1); +console.log(res8) // [1] + +const res9 = await client.json.numIncrBy("crashes", "$", 1.5); +console.log(res9) // [2.5] + +const res10 = await client.json.numIncrBy("crashes", "$", -0.75); +console.log(res10) // [1.75] +// STEP_END + +// REMOVE_START +assert.deepEqual(res10, [1.75]) +// REMOVE_END + +// STEP_START arr +const res11 = await client.json.set("newbike", "$", ["Deimos", {"crashes": 0 }, null]); +console.log(res11); // OK + +const res12 = await client.json.get("newbike", { path: "$" }); +console.log(res12); // [[ 'Deimos', { crashes: 0 }, null ]] + +const res13 = await client.json.get("newbike", { path: "$[1].crashes" }); +console.log(res13); // [0] + +const res14 = await client.json.del("newbike", { path: "$.[-1]"} ); +console.log(res14); // 1 + +const res15 = await client.json.get("newbike", { path: "$" }); +console.log(res15); // [[ 'Deimos', { crashes: 0 } ]] +// STEP_END + +// REMOVE_START +assert.deepEqual(res15, [["Deimos", { + "crashes": 0 +}]]); +// REMOVE_END + +// STEP_START arr2 +const res16 = await client.json.set("riders", "$", []); +console.log(res16); // OK + +const res17 = await client.json.arrAppend("riders", "$", "Norem"); +console.log(res17); // [1] + +const res18 = await client.json.get("riders", { path: "$" }); +console.log(res18); // [[ 'Norem' ]] + +const res19 = await client.json.arrInsert("riders", "$", 1, "Prickett", "Royse", "Castilla"); +console.log(res19); // [4] + +const res20 = await client.json.get("riders", { path: "$" }); +console.log(res20); // [[ 'Norem', 'Prickett', 'Royse', 'Castilla' ]] + +const res21 = await client.json.arrTrim("riders", "$", 1, 1); +console.log(res21); // [1] + +const res22 = await client.json.get("riders", { path: "$" }); +console.log(res22); // [[ 'Prickett' ]] + +const res23 = await client.json.arrPop("riders", { path: "$" }); +console.log(res23); // [ 'Prickett' ] + +const res24 = await client.json.arrPop("riders", { path: "$" }); +console.log(res24); // [null] +// STEP_END + +// REMOVE_START +assert.deepEqual(res24, [null]); +// REMOVE_END + +// STEP_START obj +const res25 = await client.json.set( + "bike:1", "$", { + "model": "Deimos", + "brand": "Ergonom", + "price": 4972 + } +); +console.log(res25); // OK + +const res26 = await client.json.objLen("bike:1", { path: "$" }); +console.log(res26); // [3] + +const res27 = await client.json.objKeys("bike:1", { path: "$" }); +console.log(res27); // [['model', 'brand', 'price']] +// STEP_END + +// REMOVE_START +assert.deepEqual(res27, [ + ["model", "brand", "price"] +]); +// REMOVE_END + +// STEP_START set_bikes +// HIDE_START +const inventoryJSON = { + "inventory": { + "mountain_bikes": [{ + "id": "bike:1", + "model": "Phoebe", + "description": "This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there\u2019s room for mudguards and a rack too. This is the bike for the rider who wants trail manners with low fuss ownership.", + "price": 1920, + "specs": { + "material": "carbon", + "weight": 13.1 + }, + "colors": ["black", "silver"], + }, + { + "id": "bike:2", + "model": "Quaoar", + "description": "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.", + "price": 2072, + "specs": { + "material": "aluminium", + "weight": 7.9 + }, + "colors": ["black", "white"], + }, + { + "id": "bike:3", + "model": "Weywot", + "description": "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.", + "price": 3264, + "specs": { + "material": "alloy", + "weight": 13.8 + }, + }, + ], + "commuter_bikes": [{ + "id": "bike:4", + "model": "Salacia", + "description": "This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance. It\u2019s for the rider who wants both efficiency and capability.", + "price": 1475, + "specs": { + "material": "aluminium", + "weight": 16.6 + }, + "colors": ["black", "silver"], + }, + { + "id": "bike:5", + "model": "Mimas", + "description": "A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.", + "price": 3941, + "specs": { + "material": "alloy", + "weight": 11.6 + }, + }, + ], + } +}; +// HIDE_END + +const res28 = await client.json.set("bikes:inventory", "$", inventoryJSON); +console.log(res28); // OK +// STEP_END + +// STEP_START get_bikes +const res29 = await client.json.get("bikes:inventory", { + path: "$.inventory.*" +}); +console.log(res29); +/* +[ + [ + { + id: 'bike:1', + model: 'Phoebe', + description: 'This is a mid-travel trail slayer that is a fantastic daily driver or one bike quiver. The Shimano Claris 8-speed groupset gives plenty of gear range to tackle hills and there’s room for mudguards and a rack too. This is the bike for the rider who wants trail manners with low fuss ownership.', + price: 1920, + specs: [Object], + colors: [Array] + }, + { + id: 'bike:2', + model: 'Quaoar', + description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.", + price: 2072, + specs: [Object], + colors: [Array] + }, + { + id: 'bike:3', + model: 'Weywot', + description: "This bike gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. A set of powerful Shimano hydraulic disc brakes provide ample stopping ability. If you're after a budget option, this is one of the best bikes you could get.", + price: 3264, + specs: [Object] + } + ], + [ + { + id: 'bike:4', + model: 'Salacia', + description: 'This bike is a great option for anyone who just wants a bike to get about on With a slick-shifting Claris gears from Shimano’s, this is a bike which doesn’t break the bank and delivers craved performance. It’s for the rider who wants both efficiency and capability.', + price: 1475, + specs: [Object], + colors: [Array] + }, + { + id: 'bike:5', + model: 'Mimas', + description: 'A real joy to ride, this bike got very high scores in last years Bike of the year report. The carefully crafted 50-34 tooth chainset and 11-32 tooth cassette give an easy-on-the-legs bottom gear for climbing, and the high-quality Vittoria Zaffiro tires give balance and grip.It includes a low-step frame , our memory foam seat, bump-resistant shocks and conveniently placed thumb throttle. Put it all together and you get a bike that helps redefine what can be done for this price.', + price: 3941, + specs: [Object] + } + ] +] +*/ +// STEP_END + +// STEP_START get_mtnbikes +const res30 = await client.json.get("bikes:inventory", { + path: "$.inventory.mountain_bikes[*].model" +}); +console.log(res30); // ['Phoebe', 'Quaoar', 'Weywot'] + +const res31 = await client.json.get("bikes:inventory", { + path: '$.inventory["mountain_bikes"][*].model' +}); +console.log(res31); // ['Phoebe', 'Quaoar', 'Weywot'] + +const res32 = await client.json.get("bikes:inventory", { + path: "$..mountain_bikes[*].model" +}); +console.log(res32); // ['Phoebe', 'Quaoar', 'Weywot'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res30, ["Phoebe", "Quaoar", "Weywot"]); +assert.deepEqual(res31, ["Phoebe", "Quaoar", "Weywot"]); +assert.deepEqual(res32, ["Phoebe", "Quaoar", "Weywot"]); +// REMOVE_END + +// STEP_START get_models +const res33 = await client.json.get("bikes:inventory", { + path: "$..model" +}); +console.log(res33); // ['Phoebe', 'Quaoar', 'Weywot', 'Salacia', 'Mimas'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res33, ["Phoebe", "Quaoar", "Weywot", "Salacia", "Mimas"]); +// REMOVE_END + +// STEP_START get2mtnbikes +const res34 = await client.json.get("bikes:inventory", { + path: "$..mountain_bikes[0:2].model" +}); +console.log(res34); // ['Phoebe', 'Quaoar'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res34, ["Phoebe", "Quaoar"]); +// REMOVE_END + +// STEP_START filter1 +const res35 = await client.json.get("bikes:inventory", { + path: "$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]" +}); +console.log(res35); +/* +[ + { + id: 'bike:2', + model: 'Quaoar', + description: "Redesigned for the 2020 model year, this bike impressed our testers and is the best all-around trail bike we've ever tested. The Shimano gear system effectively does away with an external cassette, so is super low maintenance in terms of wear and teaawait client. All in all it's an impressive package for the price, making it very competitive.", + price: 2072, + specs: { material: 'aluminium', weight: 7.9 }, + colors: [ 'black', 'white' ] + } +] +*/ +// STEP_END + +// STEP_START filter2 +// names of bikes made from an alloy +const res36 = await client.json.get("bikes:inventory", { + path: "$..[?(@.specs.material == 'alloy')].model" +}); +console.log(res36); // ['Weywot', 'Mimas'] +// STEP_END +// REMOVE_START +assert.deepEqual(res36, ["Weywot", "Mimas"]); +// REMOVE_END + +// STEP_START filter3 +const res37 = await client.json.get("bikes:inventory", { + path: "$..[?(@.specs.material =~ '(?i)al')].model" +}); +console.log(res37); // ['Quaoar', 'Weywot', 'Salacia', 'Mimas'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res37, ["Quaoar", "Weywot", "Salacia", "Mimas"]); +// REMOVE_END + +// STEP_START filter4 +const res37a = await client.json.set( + 'bikes:inventory', + '$.inventory.mountain_bikes[0].regex_pat', + '(?i)al' +); + +const res37b = await client.json.set( + 'bikes:inventory', + '$.inventory.mountain_bikes[1].regex_pat', + '(?i)al' +); + +const res37c = await client.json.set( + 'bikes:inventory', + '$.inventory.mountain_bikes[2].regex_pat', + '(?i)al' +); + +const res37d = await client.json.get( + 'bikes:inventory', + { path: '$.inventory.mountain_bikes[?(@.specs.material =~ @.regex_pat)].model' } +); +console.log(res37d); // ['Quaoar', 'Weywot'] +// STEP_END + +// STEP_START update_bikes +const res38 = await client.json.get("bikes:inventory", { + path: "$..price" +}); +console.log(res38); // [1920, 2072, 3264, 1475, 3941] + +const res39 = await client.json.numIncrBy("bikes:inventory", "$..price", -100); +console.log(res39); // [1820, 1972, 3164, 1375, 3841] + +const res40 = await client.json.numIncrBy("bikes:inventory", "$..price", 100); +console.log(res40); // [1920, 2072, 3264, 1475, 3941] +// STEP_END + +// REMOVE_START +assert.deepEqual(res40.sort(), [1475, 1920, 2072, 3264, 3941]); +// REMOVE_END + +// STEP_START update_filters1 +const res40a = await client.json.set( + 'bikes:inventory', + '$.inventory.*[?(@.price<2000)].price', + 1500 +); + +// Get all prices from the inventory +const res40b = await client.json.get( + 'bikes:inventory', + { path: "$..price" } +); +console.log(res40b); // [1500, 2072, 3264, 1500, 3941] +// STEP_END + +// STEP_START update_filters2 +const res41 = await client.json.arrAppend( + "bikes:inventory", "$.inventory.*[?(@.price<2000)].colors", "pink" +); +console.log(res41); // [3, 3] + +const res42 = await client.json.get("bikes:inventory", { + path: "$..[*].colors" +}); +console.log(res42); // [['black', 'silver', 'pink'], ['black', 'white'], ['black', 'silver', 'pink']] +// STEP_END + +// REMOVE_START +assert.deepEqual(res42, [ + ["black", "silver", "pink"], + ["black", "white"], + ["black", "silver", "pink"], +]); +await client.close(); +// REMOVE_END diff --git a/doctests/dt-list.js b/doctests/dt-list.js new file mode 100644 index 00000000000..a2d0fb86c66 --- /dev/null +++ b/doctests/dt-list.js @@ -0,0 +1,329 @@ +// EXAMPLE: list_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END +// REMOVE_START +await client.del('bikes:repairs'); +await client.del('bikes:finished'); +// REMOVE_END + +// STEP_START queue +const res1 = await client.lPush('bikes:repairs', 'bike:1'); +console.log(res1); // 1 + +const res2 = await client.lPush('bikes:repairs', 'bike:2'); +console.log(res2); // 2 + +const res3 = await client.rPop('bikes:repairs'); +console.log(res3); // bike:1 + +const res4 = await client.rPop('bikes:repairs'); +console.log(res4); // bike:2 +// STEP_END + +// REMOVE_START +assert.equal(res1, 1); +assert.equal(res2, 2); +assert.equal(res3, 'bike:1'); +assert.equal(res4, 'bike:2'); +// REMOVE_END + +// STEP_START stack +const res5 = await client.lPush('bikes:repairs', 'bike:1'); +console.log(res5); // 1 + +const res6 = await client.lPush('bikes:repairs', 'bike:2'); +console.log(res6); // 2 + +const res7 = await client.lPop('bikes:repairs'); +console.log(res7); // bike:2 + +const res8 = await client.lPop('bikes:repairs'); +console.log(res8); // bike:1 +// STEP_END + +// REMOVE_START +assert.equal(res5, 1); +assert.equal(res6, 2); +assert.equal(res7, 'bike:2'); +assert.equal(res8, 'bike:1'); +// REMOVE_END + +// STEP_START lLen +const res9 = await client.lLen('bikes:repairs'); +console.log(res9); // 0 +// STEP_END + +// REMOVE_START +assert.equal(res9, 0); +// REMOVE_END + +// STEP_START lMove_lRange +const res10 = await client.lPush('bikes:repairs', 'bike:1'); +console.log(res10); // 1 + +const res11 = await client.lPush('bikes:repairs', 'bike:2'); +console.log(res11); // 2 + +const res12 = await client.lMove('bikes:repairs', 'bikes:finished', 'LEFT', 'LEFT'); +console.log(res12); // 'bike:2' + +const res13 = await client.lRange('bikes:repairs', 0, -1); +console.log(res13); // ['bike:1'] + +const res14 = await client.lRange('bikes:finished', 0, -1); +console.log(res14); // ['bike:2'] +// STEP_END + +// REMOVE_START +assert.equal(res10, 1); +assert.equal(res11, 2); +assert.equal(res12, 'bike:2'); +assert.deepEqual(res13, ['bike:1']); +assert.deepEqual(res14, ['bike:2']); +await client.del('bikes:repairs'); +// REMOVE_END + +// STEP_START lPush_rPush +const res15 = await client.rPush('bikes:repairs', 'bike:1'); +console.log(res15); // 1 + +const res16 = await client.rPush('bikes:repairs', 'bike:2'); +console.log(res16); // 2 + +const res17 = await client.lPush('bikes:repairs', 'bike:important_bike'); +console.log(res17); // 3 + +const res18 = await client.lRange('bikes:repairs', 0, -1); +console.log(res18); // ['bike:important_bike', 'bike:1', 'bike:2'] +// STEP_END + +// REMOVE_START +assert.equal(res15, 1); +assert.equal(res16, 2); +assert.equal(res17, 3); +assert.deepEqual(res18, ['bike:important_bike', 'bike:1', 'bike:2']); +await client.del('bikes:repairs'); +// REMOVE_END + +// STEP_START variadic +const res19 = await client.rPush('bikes:repairs', ['bike:1', 'bike:2', 'bike:3']); +console.log(res19); // 3 + +const res20 = await client.lPush( + 'bikes:repairs', ['bike:important_bike', 'bike:very_important_bike'] +); +console.log(res20); // 5 + +const res21 = await client.lRange('bikes:repairs', 0, -1); +console.log(res21); // ['bike:very_important_bike', 'bike:important_bike', 'bike:1', 'bike:2', 'bike:3'] +// STEP_END + +// REMOVE_START +assert.equal(res19, 3); +assert.equal(res20, 5); +assert.deepEqual(res21, [ + 'bike:very_important_bike', + 'bike:important_bike', + 'bike:1', + 'bike:2', + 'bike:3', +]); +await client.del('bikes:repairs'); +// REMOVE_END + +// STEP_START lPop_rPop +const res22 = await client.rPush('bikes:repairs', ['bike:1', 'bike:2', 'bike:3']); +console.log(res22); // 3 + +const res23 = await client.rPop('bikes:repairs'); +console.log(res23); // 'bike:3' + +const res24 = await client.lPop('bikes:repairs'); +console.log(res24); // 'bike:1' + +const res25 = await client.rPop('bikes:repairs'); +console.log(res25); // 'bike:2' + +const res26 = await client.rPop('bikes:repairs'); +console.log(res26); // null +// STEP_END + +// REMOVE_START +assert.deepEqual(res22, 3); +assert.equal(res23, 'bike:3'); +assert.equal(res24, 'bike:1'); +assert.equal(res25, 'bike:2'); +assert.equal(res26, null); +// REMOVE_END + +// STEP_START lTrim +const res27 = await client.lPush( + 'bikes:repairs', ['bike:1', 'bike:2', 'bike:3', 'bike:4', 'bike:5'] +); +console.log(res27); // 5 + +const res28 = await client.lTrim('bikes:repairs', 0, 2); +console.log(res28); // OK + +const res29 = await client.lRange('bikes:repairs', 0, -1); +console.log(res29); // ['bike:5', 'bike:4', 'bike:3'] +// STEP_END + +// REMOVE_START +assert.equal(res27, 5); +assert.equal(res28, 'OK'); +assert.deepEqual(res29, ['bike:5', 'bike:4', 'bike:3']); +await client.del('bikes:repairs'); +// REMOVE_END + +// STEP_START lTrim_end_of_list +const res27eol = await client.rPush( + 'bikes:repairs', ['bike:1', 'bike:2', 'bike:3', 'bike:4', 'bike:5'] +); +console.log(res27eol); // 5 + +const res28eol = await client.lTrim('bikes:repairs', -3, -1); +console.log(res28eol); // 'OK' + +const res29eol = await client.lRange('bikes:repairs', 0, -1); +console.log(res29eol); // ['bike:3', 'bike:4', 'bike:5'] +// STEP_END + +// REMOVE_START +assert.equal(res27eol, 5); +assert.equal(res28eol, 'OK'); +assert.deepEqual(res29eol, ['bike:3', 'bike:4', 'bike:5']); +await client.del('bikes:repairs'); +// REMOVE_END + +// STEP_START brPop +const res31 = await client.rPush('bikes:repairs', ['bike:1', 'bike:2']); +console.log(res31); // 2 + +const res32 = await client.brPop('bikes:repairs', 1); +console.log(res32); // { key: 'bikes:repairs', element: 'bike:2' } + +const res33 = await client.brPop('bikes:repairs', 1); +console.log(res33); // { key: 'bikes:repairs', element: 'bike:1' } + +const res34 = await client.brPop('bikes:repairs', 1); +console.log(res34); // null +// STEP_END + +// REMOVE_START +assert.equal(res31, 2); +assert.deepEqual(res32, { key: 'bikes:repairs', element: 'bike:2' }); +assert.deepEqual(res33, { key: 'bikes:repairs', element: 'bike:1' }); +assert.equal(res34, null); +await client.del('bikes:repairs'); +await client.del('new_bikes'); +// REMOVE_END + +// STEP_START rule_1 +const res35 = await client.del('new_bikes'); +console.log(res35); // 0 + +const res36 = await client.lPush('new_bikes', ['bike:1', 'bike:2', 'bike:3']); +console.log(res36); // 3 +// STEP_END + +// REMOVE_START +assert.equal(res35, 0); +assert.equal(res36, 3); +await client.del('new_bikes'); +// REMOVE_END + +// STEP_START rule_1.1 +const res37 = await client.set('new_bikes', 'bike:1'); +console.log(res37); // 'OK' + +const res38 = await client.type('new_bikes'); +console.log(res38); // 'string' + +try { + const res39 = await client.lPush('new_bikes', 'bike:2', 'bike:3'); + // redis.exceptions.ResponseError: + // [SimpleError: WRONGTYPE Operation against a key holding the wrong kind of value] +} +catch(e){ + console.log(e); +} +// STEP_END + +// REMOVE_START +assert.equal(res37, 'OK'); +assert.equal(res38, 'string'); +await client.del('new_bikes'); +// REMOVE_END + +// STEP_START rule_2 +await client.lPush('bikes:repairs', ['bike:1', 'bike:2', 'bike:3']); +console.log(res36); // 3 + +const res40 = await client.exists('bikes:repairs') +console.log(res40); // 1 + +const res41 = await client.lPop('bikes:repairs'); +console.log(res41); // 'bike:3' + +const res42 = await client.lPop('bikes:repairs'); +console.log(res42); // 'bike:2' + +const res43 = await client.lPop('bikes:repairs'); +console.log(res43); // 'bike:1' + +const res44 = await client.exists('bikes:repairs'); +console.log(res44); // 0 +// STEP_END + +// REMOVE_START +assert.equal(res40, 1); +assert.equal(res41, 'bike:3'); +assert.equal(res42, 'bike:2'); +assert.equal(res43, 'bike:1'); +assert.equal(res44, 0); +await client.del('bikes:repairs'); +// REMOVE_END + +// STEP_START rule_3 +const res45 = await client.del('bikes:repairs'); +console.log(res45); // 0 + +const res46 = await client.lLen('bikes:repairs'); +console.log(res46); // 0 + +const res47 = await client.lPop('bikes:repairs'); +console.log(res47); // null +// STEP_END + +// REMOVE_START +assert.equal(res45, 0); +assert.equal(res46, 0); +assert.equal(res47, null); +// REMOVE_END + +// STEP_START lTrim.1 +const res48 = await client.lPush( + 'bikes:repairs', ['bike:1', 'bike:2', 'bike:3', 'bike:4', 'bike:5'] +); +console.log(res48); // 5 + +const res49 = await client.lTrim('bikes:repairs', 0, 2); +console.log(res49); // 'OK' + +const res50 = await client.lRange('bikes:repairs', 0, -1); +console.log(res50); // ['bike:5', 'bike:4', 'bike:3'] +// STEP_END + +// REMOVE_START +assert.equal(res48, 5); +assert.equal(res49, 'OK'); +assert.deepEqual(res50, ['bike:5', 'bike:4', 'bike:3']); +await client.del('bikes:repairs'); +await client.close(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/dt-set.js b/doctests/dt-set.js new file mode 100644 index 00000000000..e3d34096399 --- /dev/null +++ b/doctests/dt-set.js @@ -0,0 +1,176 @@ +// EXAMPLE: sets_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END +// REMOVE_START +await client.del('bikes:racing:france') +await client.del('bikes:racing:usa') +// REMOVE_END + +// STEP_START sAdd +const res1 = await client.sAdd('bikes:racing:france', 'bike:1') +console.log(res1) // >>> 1 + +const res2 = await client.sAdd('bikes:racing:france', 'bike:1') +console.log(res2) // >>> 0 +const res3 = await client.sAdd('bikes:racing:france', ['bike:2', 'bike:3']) +console.log(res3) // >>> 2 +const res4 = await client.sAdd('bikes:racing:usa', ['bike:1', 'bike:4']) +console.log(res4) // >>> 2 +// STEP_END + +// REMOVE_START +assert.equal(res1, 1) +assert.equal(res2, 0) +assert.equal(res3, 2) +assert.equal(res4, 2) +// REMOVE_END + +// STEP_START sIsMember +// HIDE_START +await client.del('bikes:racing:france') +await client.del('bikes:racing:usa') +await client.sAdd('bikes:racing:france', 'bike:1', 'bike:2', 'bike:3') +await client.sAdd('bikes:racing:usa', 'bike:1', 'bike:4') +// HIDE_END +const res5 = await client.sIsMember('bikes:racing:usa', 'bike:1') +console.log(res5) // >>> 1 + +const res6 = await client.sIsMember('bikes:racing:usa', 'bike:2') +console.log(res6) // >>> 0 +// STEP_END + +// REMOVE_START +assert.equal(res5, 1) +assert.equal(res6, 0) +// REMOVE_END + +// STEP_START sinster +// HIDE_START +await client.del('bikes:racing:france') +await client.del('bikes:racing:usa') +await client.sAdd('bikes:racing:france', 'bike:1', 'bike:2', 'bike:3') +await client.sAdd('bikes:racing:usa', 'bike:1', 'bike:4') +// HIDE_END +const res7 = await client.sInter('bikes:racing:france', 'bikes:racing:usa') +console.log(res7) // >>> {'bike:1'} +// STEP_END + +// REMOVE_START +assert.deepEqual(res7, [ 'bike:1' ]) +// REMOVE_END + +// STEP_START sCard +// HIDE_START +await client.del('bikes:racing:france') +await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3']) +// HIDE_END +const res8 = await client.sCard('bikes:racing:france') +console.log(res8) // >>> 3 +// STEP_END + +// REMOVE_START +assert.equal(res8, 3) +await client.del('bikes:racing:france') +// REMOVE_END + +// STEP_START sAdd_sMembers +const res9 = await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3']) +console.log(res9) // >>> 3 + +const res10 = await client.sMembers('bikes:racing:france') +console.log(res10) // >>> ['bike:1', 'bike:2', 'bike:3'] +// STEP_END + +// REMOVE_START +assert.equal(res9, 3) +assert.deepEqual(res10.sort(), ['bike:1', 'bike:2', 'bike:3']) +// REMOVE_END + +// STEP_START smIsMember +const res11 = await client.sIsMember('bikes:racing:france', 'bike:1') +console.log(res11) // >>> 1 + +const res12 = await client.smIsMember('bikes:racing:france', ['bike:2', 'bike:3', 'bike:4']) +console.log(res12) // >>> [1, 1, 0] +// STEP_END + +// REMOVE_START +assert.equal(res11, 1) +assert.deepEqual(res12, [1, 1, 0]) +// REMOVE_END + +// STEP_START sDiff +await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3']) +await client.sAdd('bikes:racing:usa', ['bike:1', 'bike:4']) +const res13 = await client.sDiff(['bikes:racing:france', 'bikes:racing:usa']) +console.log(res13) // >>> [ 'bike:2', 'bike:3' ] +// STEP_END + +// REMOVE_START +assert.deepEqual(res13.sort(), ['bike:2', 'bike:3'].sort()) +await client.del('bikes:racing:france') +await client.del('bikes:racing:usa') +// REMOVE_END + +// STEP_START multisets +await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3']) +await client.sAdd('bikes:racing:usa', ['bike:1', 'bike:4']) +await client.sAdd('bikes:racing:italy', ['bike:1', 'bike:2', 'bike:3', 'bike:4']) + +const res14 = await client.sInter( + ['bikes:racing:france', 'bikes:racing:usa', 'bikes:racing:italy'] +) +console.log(res14) // >>> ['bike:1'] + +const res15 = await client.sUnion( + ['bikes:racing:france', 'bikes:racing:usa', 'bikes:racing:italy'] +) +console.log(res15) // >>> ['bike:1', 'bike:2', 'bike:3', 'bike:4'] + +const res16 = await client.sDiff(['bikes:racing:france', 'bikes:racing:usa', 'bikes:racing:italy']) +console.log(res16) // >>> [] + +const res17 = await client.sDiff(['bikes:racing:usa', 'bikes:racing:france']) +console.log(res17) // >>> ['bike:4'] + +const res18 = await client.sDiff(['bikes:racing:france', 'bikes:racing:usa']) +console.log(res18) // >>> ['bike:2', 'bike:3'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res14, ['bike:1']) +assert.deepEqual(res15.sort(), ['bike:1', 'bike:2', 'bike:3', 'bike:4']) +assert.deepEqual(res16, []) +assert.deepEqual(res17, ['bike:4']) +assert.deepEqual(res18.sort(), ['bike:2', 'bike:3'].sort()) +await client.del('bikes:racing:france') +await client.del('bikes:racing:usa') +await client.del('bikes:racing:italy') +// REMOVE_END + +// STEP_START sRem +await client.sAdd('bikes:racing:france', ['bike:1', 'bike:2', 'bike:3', 'bike:4', 'bike:5']) + +const res19 = await client.sRem('bikes:racing:france', 'bike:1') +console.log(res19) // >>> 1 + +const res20 = await client.sPop('bikes:racing:france') +console.log(res20) // >>> bike:3 or other random value + +const res21 = await client.sMembers('bikes:racing:france') +console.log(res21) // >>> ['bike:2', 'bike:4', 'bike:5']; depends on previous result + +const res22 = await client.sRandMember('bikes:racing:france') +console.log(res22) // >>> bike:4 or other random value +// STEP_END + +// REMOVE_START +assert.equal(res19, 1) +await client.close() +// none of the other results are deterministic +// REMOVE_END diff --git a/doctests/dt-ss.js b/doctests/dt-ss.js new file mode 100644 index 00000000000..bba85b11580 --- /dev/null +++ b/doctests/dt-ss.js @@ -0,0 +1,162 @@ +// EXAMPLE: ss_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END + +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START zadd +const res1 = await client.zAdd('racer_scores', { score: 10, value: 'Norem' }); +console.log(res1); // >>> 1 + +const res2 = await client.zAdd('racer_scores', { score: 12, value: 'Castilla' }); +console.log(res2); // >>> 1 + +const res3 = await client.zAdd('racer_scores', [ + { score: 8, value: 'Sam-Bodden' }, + { score: 10, value: 'Royce' }, + { score: 6, value: 'Ford' }, + { score: 14, value: 'Prickett' }, + { score: 12, value: 'Castilla' } +]); +console.log(res3); // >>> 4 +// STEP_END + +// REMOVE_START +assert.equal(res1, 1) +assert.equal(res2, 1) +assert.equal(res3, 4) +// REMOVE_END + +// REMOVE_START +const count = await client.zCard('racer_scores'); +console.assert(count === 6); +// REMOVE_END + +// STEP_START zrange +const res4 = await client.zRange('racer_scores', 0, -1); +console.log(res4); // >>> ['Ford', 'Sam-Bodden', 'Norem', 'Royce', 'Castilla', 'Prickett'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res4, ['Ford', 'Sam-Bodden', 'Norem', 'Royce', 'Castilla', 'Prickett']) +// REMOVE_END + +// STEP_START zrange_withscores +const res6 = await client.zRangeWithScores('racer_scores', 0, -1); +console.log(res6); +// >>> [ +// { value: 'Ford', score: 6 }, { value: 'Sam-Bodden', score: 8 }, +// { value: 'Norem', score: 10 }, { value: 'Royce', score: 10 }, +// { value: 'Castilla', score: 12 }, { value: 'Prickett', score: 14 } +// ] +// STEP_END + +// REMOVE_START +assert.deepEqual(res6, [ { value: 'Ford', score: 6 }, { value: 'Sam-Bodden', score: 8 }, { value: 'Norem', score: 10 }, { value: 'Royce', score: 10 }, { value: 'Castilla', score: 12 }, { value: 'Prickett', score: 14 } ] +) +// REMOVE_END + +// STEP_START zrangebyscore +const res7 = await client.zRangeByScore('racer_scores', '-inf', 10); +console.log(res7); // >>> ['Ford', 'Sam-Bodden', 'Norem', 'Royce'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res7, ['Ford', 'Sam-Bodden', 'Norem', 'Royce']) +// REMOVE_END + +// STEP_START zremrangebyscore +const res8 = await client.zRem('racer_scores', 'Castilla'); +console.log(res8); // >>> 1 + +const res9 = await client.zRemRangeByScore('racer_scores', '-inf', 9); +console.log(res9); // >>> 2 + +// REMOVE_START +assert.equal(res8, 1) +assert.equal(res9, 2) +// REMOVE_END + +const res10 = await client.zRange('racer_scores', 0, -1); +console.log(res10); // >>> ['Norem', 'Royce', 'Prickett'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res10, ['Norem', 'Royce', 'Prickett']) +// REMOVE_END + +// REMOVE_START +const count2 = await client.zCard('racer_scores'); +console.assert(count2 === 3); +// REMOVE_END + +// STEP_START zrank +const res11 = await client.zRank('racer_scores', 'Norem'); +console.log(res11); // >>> 0 + +const res12 = await client.zRevRank('racer_scores', 'Norem'); +console.log(res12); // >>> 2 +// STEP_END + +// STEP_START zadd_lex +const res13 = await client.zAdd('racer_scores', [ + { score: 0, value: 'Norem' }, + { score: 0, value: 'Sam-Bodden' }, + { score: 0, value: 'Royce' }, + { score: 0, value: 'Ford' }, + { score: 0, value: 'Prickett' }, + { score: 0, value: 'Castilla' } +]); +console.log(res13); // >>> 3 + +// REMOVE_START +assert.equal(count2, 3) +assert.equal(res11, 0) +assert.equal(res12, 2) +assert.equal(res13, 3) +// REMOVE_END + +const res14 = await client.zRange('racer_scores', 0, -1); +console.log(res14); // >>> ['Castilla', 'Ford', 'Norem', 'Prickett', 'Royce', 'Sam-Bodden'] + +const res15 = await client.zRangeByLex('racer_scores', '[A', '[L'); +console.log(res15); // >>> ['Castilla', 'Ford'] +// STEP_END + +// REMOVE_START +assert.deepEqual(res14, ['Castilla', 'Ford', 'Norem', 'Prickett', 'Royce', 'Sam-Bodden']) +assert.deepEqual(res15, ['Castilla', 'Ford']) +// REMOVE_END + +// STEP_START leaderboard +const res16 = await client.zAdd('racer_scores', { score: 100, value: 'Wood' }); +console.log(res16); // >>> 1 + +const res17 = await client.zAdd('racer_scores', { score: 100, value: 'Henshaw' }); +console.log(res17); // >>> 1 + +const res18 = await client.zAdd('racer_scores', { score: 150, value: 'Henshaw' }, { nx: true }); +console.log(res18); // >>> 0 + +const res19 = await client.zIncrBy('racer_scores', 50, 'Wood'); +console.log(res19); // >>> 150.0 + +const res20 = await client.zIncrBy('racer_scores', 50, 'Henshaw'); +console.log(res20); // >>> 200.0 +// STEP_END + +// REMOVE_START +assert.equal(res16, 1) +assert.equal(res17, 1) +assert.equal(res18, 0) +assert.equal(res19, 150.0) +assert.equal(res20, 200.0) +await client.close(); +// REMOVE_END diff --git a/doctests/dt-streams.js b/doctests/dt-streams.js new file mode 100644 index 00000000000..94e415ea4e7 --- /dev/null +++ b/doctests/dt-streams.js @@ -0,0 +1,346 @@ +// EXAMPLE: stream_tutorial +// HIDE_START +import assert from 'assert'; +import { + createClient +} from 'redis'; + +const client = await createClient(); +await client.connect(); +// HIDE_END +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START xAdd +const res1 = await client.xAdd( + 'race:france', '*', { + 'rider': 'Castilla', + 'speed': '30.2', + 'position': '1', + 'location_id': '1' + } +); +console.log(res1); // >>> 1700073067968-0 N.B. actual values will differ from these examples + +const res2 = await client.xAdd( + 'race:france', '*', { + 'rider': 'Norem', + 'speed': '28.8', + 'position': '3', + 'location_id': '1' + }, +); +console.log(res2); // >>> 1692629594113-0 + +const res3 = await client.xAdd( + 'race:france', '*', { + 'rider': 'Prickett', + 'speed': '29.7', + 'position': '2', + 'location_id': '1' + }, +); +console.log(res3); // >>> 1692629613374-0 +// STEP_END + +// REMOVE_START +assert.equal(await client.xLen('race:france'), 3); +// REMOVE_END + +// STEP_START xRange +const res4 = await client.xRange('race:france', '1691765278160-0', '+', {COUNT: 2}); +console.log(res4); // >>> [('1692629576966-0', {'rider': 'Castilla', 'speed': '30.2', 'position': '1', 'location_id': '1'}), ('1692629594113-0', {'rider': 'Norem', 'speed': '28.8', 'position': '3', 'location_id': '1'})] +// STEP_END + +// STEP_START xread_block +const res5 = await client.xRead({ + key: 'race:france', + id: '0-0' +}, { + count: 100, + block: 300 +}); +console.log(res5); // >>> [['race:france', [('1692629576966-0', {'rider': 'Castilla', 'speed': '30.2', 'position': '1', 'location_id': '1'}), ('1692629594113-0', {'rider': 'Norem', 'speed': '28.8', 'position': '3', 'location_id': '1'}), ('1692629613374-0', {'rider': 'Prickett', 'speed': '29.7', 'position': '2', 'location_id': '1'})]]] +// STEP_END + +// STEP_START xAdd_2 +const res6 = await client.xAdd( + 'race:france', '*', { + 'rider': 'Castilla', + 'speed': '29.9', + 'position': '1', + 'location_id': '2' + } +); +console.log(res6); // >>> 1692629676124-0 +// STEP_END + +// STEP_START xlen +const res7 = await client.xLen('race:france'); +console.log(res7); // >>> 4 +// STEP_END + + +// STEP_START xAdd_id +const res8 = await client.xAdd('race:usa', '0-1', { + 'racer': 'Castilla' +}); +console.log(res8); // >>> 0-1 + +const res9 = await client.xAdd('race:usa', '0-2', { + 'racer': 'Norem' +}); +console.log(res9); // >>> 0-2 +// STEP_END + +// STEP_START xAdd_bad_id +try { + const res10 = await client.xAdd('race:usa', '0-1', { + 'racer': 'Prickett' + }); + console.log(res10); // >>> 0-1 +} catch (error) { + console.error(error); // >>> WRONGID +} +// STEP_END + +// STEP_START xadd_7 +const res11a = await client.xAdd('race:usa', '0-*', { racer: 'Norem' }); +console.log(res11a); // >>> 0-3 +// STEP_END + +// STEP_START xRange_all +const res11 = await client.xRange('race:france', '-', '+'); +console.log(res11); // >>> [('1692629576966-0', {'rider': 'Castilla', 'speed': '30.2', 'position': '1', 'location_id': '1'}), ('1692629594113-0', {'rider': 'Norem', 'speed': '28.8', 'position': '3', 'location_id': '1'}), ('1692629613374-0', {'rider': 'Prickett', 'speed': '29.7', 'position': '2', 'location_id': '1'}), ('1692629676124-0', {'rider': 'Castilla', 'speed': '29.9', 'position': '1', 'location_id': '2'})] +// STEP_END + +// STEP_START xRange_time +const res12 = await client.xRange('race:france', '1692629576965', '1692629576967'); +console.log(res12); // >>> [('1692629576966-0', {'rider': 'Castilla', 'speed': '30.2', 'position': '1', 'location_id': '1'})] +// STEP_END + +// STEP_START xRange_step_1 +const res13 = await client.xRange('race:france', '-', '+', {COUNT: 2}); +console.log(res13); // >>> [('1692629576966-0', {'rider': 'Castilla', 'speed': '30.2', 'position': '1', 'location_id': '1'}), ('1692629594113-0', {'rider': 'Norem', 'speed': '28.8', 'position': '3', 'location_id': '1'})] +// STEP_END + +// STEP_START xRange_step_2 +const res14 = await client.xRange('race:france', '(1692629594113-0', '+', {COUNT: 2}); +console.log(res14); // >>> [('1692629613374-0', {'rider': 'Prickett', 'speed': '29.7', 'position': '2', 'location_id': '1'}), ('1692629676124-0', {'rider': 'Castilla', 'speed': '29.9', 'position': '1', 'location_id': '2'})] +// STEP_END + +// STEP_START xRange_empty +const res15 = await client.xRange('race:france', '(1692629676124-0', '+', {COUNT: 2}); +console.log(res15); // >>> [] +// STEP_END + +// STEP_START xrevrange +const res16 = await client.xRevRange('race:france', '+', '-', {COUNT: 1}); +console.log( + res16 +); // >>> [('1692629676124-0', {'rider': 'Castilla', 'speed': '29.9', 'position': '1', 'location_id': '2'})] +// STEP_END + +// STEP_START xread +const res17 = await client.xRead({ + key: 'race:france', + id: '0-0' +}, { + count: 2 +}); +console.log(res17); // >>> [['race:france', [('1692629576966-0', {'rider': 'Castilla', 'speed': '30.2', 'position': '1', 'location_id': '1'}), ('1692629594113-0', {'rider': 'Norem', 'speed': '28.8', 'position': '3', 'location_id': '1'})]]] +// STEP_END + +// STEP_START xgroup_create +const res18 = await client.xGroupCreate('race:france', 'france_riders', '$'); +console.log(res18); // >>> True +// STEP_END + +// STEP_START xgroup_create_mkstream +const res19 = await client.xGroupCreate('race:italy', 'italy_riders', '$', { + 'MKSTREAM': true +}); +console.log(res19); // >>> True +// STEP_END + +// STEP_START xgroup_read +await client.xAdd('race:italy', '*', { + 'rider': 'Castilla' +}); +await client.xAdd('race:italy', '*', { + 'rider': 'Royce' +}); +await client.xAdd('race:italy', '*', { + 'rider': 'Sam-Bodden' +}); +await client.xAdd('race:italy', '*', { + 'rider': 'Prickett' +}); +await client.xAdd('race:italy', '*', { + 'rider': 'Norem' +}); + +const res20 = await client.xReadGroup( + 'italy_riders', + 'Alice', { + key: 'race:italy', + id: '>' + }, { + 'COUNT': 1 + } +); +console.log(res20); // >>> [['race:italy', [('1692629925771-0', {'rider': 'Castilla'})]]] +// STEP_END + +// STEP_START xgroup_read_id +const res21 = await client.xReadGroup( + 'italy_riders', + 'Alice', { + key: 'race:italy', + id: '0' + }, { + 'COUNT': 1 + } +); +console.log(res21); // >>> [['race:italy', [('1692629925771-0', {'rider': 'Castilla'})]]] +// STEP_END + +// STEP_START xack +const res22 = await client.xAck('race:italy', 'italy_riders', '1692629925771-0') +console.log(res22); // >>> 1 + +const res23 = await client.xReadGroup( + 'italy_riders', + 'Alice', { + key: 'race:italy', + id: '0' + }, { + 'COUNT': 1 + } +); +console.log(res23); // >>> [['race:italy', []]] +// STEP_END + +// STEP_START xgroup_read_bob +const res24 = await client.xReadGroup( + 'italy_riders', + 'Bob', { + key: 'race:italy', + id: '>' + }, { + 'COUNT': 2 + } +); +console.log(res24); // >>> [['race:italy', [('1692629925789-0', {'rider': 'Royce'}), ('1692629925790-0', {'rider': 'Sam-Bodden'})]]] +// STEP_END + +// STEP_START xpending +const res25 = await client.xPending('race:italy', 'italy_riders'); +console.log(res25); // >>> {'pending': 2, 'min': '1692629925789-0', 'max': '1692629925790-0', 'consumers': [{'name': 'Bob', 'pending': 2}]} +// STEP_END + +// STEP_START xpending_plus_minus +const res26 = await client.xPendingRange('race:italy', 'italy_riders', '-', '+', 10); +console.log(res26); // >>> [{'message_id': '1692629925789-0', 'consumer': 'Bob', 'time_since_delivered': 31084, 'times_delivered': 1}, {'message_id': '1692629925790-0', 'consumer': 'Bob', 'time_since_delivered': 31084, 'times_delivered': 1}] +// STEP_END + +// STEP_START xRange_pending +const res27 = await client.xRange('race:italy', '1692629925789-0', '1692629925789-0'); +console.log(res27); // >>> [('1692629925789-0', {'rider': 'Royce'})] +// STEP_END + +// STEP_START xclaim +const res28 = await client.xClaim( + 'race:italy', 'italy_riders', 'Alice', 60000, ['1692629925789-0'] +); +console.log(res28); // >>> [('1692629925789-0', {'rider': 'Royce'})] +// STEP_END + +// STEP_START xautoclaim +const res29 = await client.xAutoClaim('race:italy', 'italy_riders', 'Alice', 1, '0-0', 1); +console.log(res29); // >>> ['1692629925790-0', [('1692629925789-0', {'rider': 'Royce'})]] +// STEP_END + +// STEP_START xautoclaim_cursor +const res30 = await client.xAutoClaim( + 'race:italy', 'italy_riders', 'Alice', 1, '(1692629925789-0', 1 +); +console.log(res30); // >>> ['0-0', [('1692629925790-0', {'rider': 'Sam-Bodden'})]] +// STEP_END + +// STEP_START xinfo +const res31 = await client.xInfoStream('race:italy'); +console.log(res31); // >>> {'length': 5, 'radix-tree-keys': 1, 'radix-tree-nodes': 2, 'last-generated-id': '1692629926436-0', 'groups': 1, 'first-entry': ('1692629925771-0', {'rider': 'Castilla'}), 'last-entry': ('1692629926436-0', {'rider': 'Norem'})} +// STEP_END + +// STEP_START xinfo_groups +const res32 = await client.xInfoGroups('race:italy'); +console.log(res32); // >>> [{'name': 'italy_riders', 'consumers': 2, 'pending': 2, 'last-delivered-id': '1692629925790-0'}] +// STEP_END + +// STEP_START xinfo_consumers +const res33 = await client.xInfoConsumers('race:italy', 'italy_riders'); +console.log(res33); // >>> [{'name': 'Alice', 'pending': 2, 'idle': 199332}, {'name': 'Bob', 'pending': 0, 'idle': 489170}] +// STEP_END + +// STEP_START maxlen +await client.xAdd('race:italy', '*', { + 'rider': 'Jones' +}, { + 'MAXLEN': 2 +}); +await client.xAdd('race:italy', '*', { + 'rider': 'Wood' +}, { + 'MAXLEN': 2 +}); +await client.xAdd('race:italy', '*', { + 'rider': 'Henshaw' +}, { + 'MAXLEN': 2 +}); + +const res34 = await client.xLen('race:italy'); +console.log(res34); // >>> 8 + +const res35 = await client.xRange('race:italy', '-', '+'); +console.log(res35); // >>> [('1692629925771-0', {'rider': 'Castilla'}), ('1692629925789-0', {'rider': 'Royce'}), ('1692629925790-0', {'rider': 'Sam-Bodden'}), ('1692629925791-0', {'rider': 'Prickett'}), ('1692629926436-0', {'rider': 'Norem'}), ('1692630612602-0', {'rider': 'Jones'}), ('1692630641947-0', {'rider': 'Wood'}), ('1692630648281-0', {'rider': 'Henshaw'})] + +await client.xAdd('race:italy', '*', { + 'rider': 'Smith' +}, { + 'MAXLEN': 2, + 'APPROXIMATE': false +}); + +const res36 = await client.xRange('race:italy', '-', '+'); +console.log(res36); // >>> [('1692630648281-0', {'rider': 'Henshaw'}), ('1692631018238-0', {'rider': 'Smith'})] +// STEP_END + +// STEP_START xTrim +const res37 = await client.xTrim('race:italy', 'MAXLEN', 10, { + 'APPROXIMATE': false +}); +console.log(res37); // >>> 0 +// STEP_END + +// STEP_START xTrim2 +const res38 = await client.xTrim('race:italy', "MAXLEN", 10); +console.log(res38); // >>> 0 +// STEP_END + +// STEP_START xDel +const res39 = await client.xRange('race:italy', '-', '+'); +console.log(res39); // >>> [('1692630648281-0', {'rider': 'Henshaw'}), ('1692631018238-0', {'rider': 'Smith'})] + +const res40 = await client.xDel('race:italy', '1692631018238-0'); +console.log(res40); // >>> 1 + +const res41 = await client.xRange('race:italy', '-', '+'); +console.log(res41); // >>> [('1692630648281-0', {'rider': 'Henshaw'})] +// STEP_END + +// REMOVE_START +await client.quit(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/dt-string.js b/doctests/dt-string.js new file mode 100644 index 00000000000..6f77709abfa --- /dev/null +++ b/doctests/dt-string.js @@ -0,0 +1,68 @@ +// EXAMPLE: set_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START set_get +const res1 = await client.set("bike:1", "Deimos"); +console.log(res1); // OK +const res2 = await client.get("bike:1"); +console.log(res2); // Deimos +// STEP_END + +// REMOVE_START +assert.equal(res1, 'OK'); +assert.equal(res2, 'Deimos'); +// REMOVE_END + +// STEP_START setnx_xx +const res3 = await client.set("bike:1", "bike", {'NX': true}); +console.log(res3); // null +console.log(await client.get("bike:1")); // Deimos +const res4 = await client.set("bike:1", "bike", {'XX': true}); +console.log(res4); // OK +// STEP_END + +// REMOVE_START +assert.equal(res3, null); +assert.equal(res4, 'OK'); +// REMOVE_END + +// STEP_START mset +const res5 = await client.mSet([ + ["bike:1", "Deimos"], + ["bike:2", "Ares"], + ["bike:3", "Vanth"] +]); + +console.log(res5); // OK +const res6 = await client.mGet(["bike:1", "bike:2", "bike:3"]); +console.log(res6); // ['Deimos', 'Ares', 'Vanth'] +// STEP_END + +// REMOVE_START +assert.equal(res5, 'OK'); +assert.deepEqual(res6, ["Deimos", "Ares", "Vanth"]); +// REMOVE_END + +// STEP_START incr +await client.set("total_crashes", 0); +const res7 = await client.incr("total_crashes"); +console.log(res7); // 1 +const res8 = await client.incrBy("total_crashes", 10); +console.log(res8); // 11 +// STEP_END + +// REMOVE_START +assert.equal(res7, 1); +assert.equal(res8, 11); + +await client.close(); +// REMOVE_END diff --git a/doctests/dt-tdigest.js b/doctests/dt-tdigest.js new file mode 100644 index 00000000000..c59168076e3 --- /dev/null +++ b/doctests/dt-tdigest.js @@ -0,0 +1,85 @@ +// EXAMPLE: tdigest_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END + +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START tdig_start +const res1 = await client.tDigest.create('bikes:sales', 100); +console.log(res1); // >>> OK + +const res2 = await client.tDigest.add('bikes:sales', [21]); +console.log(res2); // >>> OK + +const res3 = await client.tDigest.add('bikes:sales', [150, 95, 75, 34]); +console.log(res3); // >>> OK +// STEP_END + +// REMOVE_START +assert.equal(res1, 'OK') +assert.equal(res2, 'OK') +assert.equal(res3, 'OK') +// REMOVE_END + +// STEP_START tdig_cdf +const res4 = await client.tDigest.create('racer_ages'); +console.log(res4); // >>> OK + +const res5 = await client.tDigest.add('racer_ages', [ + 45.88, 44.2, 58.03, 19.76, 39.84, 69.28, 50.97, 25.41, 19.27, 85.71, 42.63 +]); +console.log(res5); // >>> OK + +const res6 = await client.tDigest.rank('racer_ages', [50]); +console.log(res6); // >>> [7] + +const res7 = await client.tDigest.rank('racer_ages', [50, 40]); +console.log(res7); // >>> [7, 4] +// STEP_END + +// REMOVE_START +assert.equal(res4, 'OK') +assert.equal(res5, 'OK') +assert.deepEqual(res6, [7]) +assert.deepEqual(res7, [7, 4]) +// REMOVE_END + +// STEP_START tdig_quant +const res8 = await client.tDigest.quantile('racer_ages', [0.5]); +console.log(res8); // >>> [44.2] + +const res9 = await client.tDigest.byRank('racer_ages', [4]); +console.log(res9); // >>> [42.63] +// STEP_END + +// STEP_START tdig_min +const res10 = await client.tDigest.min('racer_ages'); +console.log(res10); // >>> 19.27 + +const res11 = await client.tDigest.max('racer_ages'); +console.log(res11); // >>> 85.71 +// STEP_END + +// REMOVE_START +assert.deepEqual(res8, [44.2]) +assert.deepEqual(res9, [42.63]) +assert.equal(res10, 19.27) +assert.equal(res11, 85.71) +// REMOVE_END + +// STEP_START tdig_reset +const res12 = await client.tDigest.reset('racer_ages'); +console.log(res12); // >>> OK +// STEP_END + +// REMOVE_START +assert.equal(res12, 'OK') +await client.close(); +// REMOVE_END diff --git a/doctests/dt-topk.js b/doctests/dt-topk.js new file mode 100644 index 00000000000..49b929aed8a --- /dev/null +++ b/doctests/dt-topk.js @@ -0,0 +1,48 @@ +// EXAMPLE: topk_tutorial +// HIDE_START +import assert from 'assert'; +import { createClient } from 'redis'; + +const client = createClient(); +await client.connect(); +// HIDE_END + +// REMOVE_START +await client.flushDb(); +// REMOVE_END + +// STEP_START topk +const res1 = await client.topK.reserve('bikes:keywords', 5, { + width: 2000, + depth: 7, + decay: 0.925 +}); +console.log(res1); // >>> OK + +const res2 = await client.topK.add('bikes:keywords', [ + 'store', + 'seat', + 'handlebars', + 'handles', + 'pedals', + 'tires', + 'store', + 'seat' +]); +console.log(res2); // >>> [null, null, null, null, null, 'handlebars', null, null] + +const res3 = await client.topK.list('bikes:keywords'); +console.log(res3); // >>> ['store', 'seat', 'pedals', 'tires', 'handles'] + +const res4 = await client.topK.query('bikes:keywords', ['store', 'handlebars']); +console.log(res4); // >>> [true, false] +// STEP_END + +// REMOVE_START +assert.equal(res1, 'OK') +assert.deepEqual(res2, [null, null, null, null, null, 'handlebars', null, null]) +assert.deepEqual(res3, ['store', 'seat', 'pedals', 'tires', 'handles']) +assert.deepEqual(res4, [1, 0]) +await client.close(); +// REMOVE_END + diff --git a/doctests/package-lock.json b/doctests/package-lock.json new file mode 100644 index 00000000000..2f30678e529 --- /dev/null +++ b/doctests/package-lock.json @@ -0,0 +1,889 @@ +{ + "name": "node-redis-doctests", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "node-redis-doctests", + "version": "1.0.0", + "dependencies": { + "@xenova/transformers": "^2.17.2", + "redis": "file:/packages/redis" + } + }, + "..": { + "name": "redis-monorepo", + "extraneous": true, + "workspaces": [ + "./packages/client", + "./packages/test-utils", + "./packages/bloom", + "./packages/json", + "./packages/search", + "./packages/time-series", + "./packages/entraid", + "./packages/redis" + ], + "devDependencies": { + "@istanbuljs/nyc-config-typescript": "^1.0.2", + "@release-it/bumper": "^7.0.5", + "@types/mocha": "^10.0.6", + "@types/node": "^20.11.16", + "gh-pages": "^6.1.1", + "mocha": "^10.2.0", + "nyc": "^15.1.0", + "release-it": "^19.0.2", + "ts-node": "^10.9.2", + "tsx": "^4.7.0", + "typedoc": "^0.25.7", + "typescript": "^5.3.3" + } + }, + "../../../../../packages/redis": {}, + "node_modules/@huggingface/jinja": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.2.2.tgz", + "integrity": "sha512-/KPde26khDUIPkTGU82jdtTW9UAuvUTumCAbFs/7giR0SxsvZC4hru51PBvpijH6BVkHcROcvZM/lpy5h1jRRA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.10.tgz", + "integrity": "sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/@xenova/transformers": { + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/@xenova/transformers/-/transformers-2.17.2.tgz", + "integrity": "sha512-lZmHqzrVIkSvZdKZEx7IYY51TK0WDrC8eR0c5IMnBsO8di8are1zzw8BlLhyO2TklZKLN5UffNGs1IJwT6oOqQ==", + "license": "Apache-2.0", + "dependencies": { + "@huggingface/jinja": "^0.2.2", + "onnxruntime-web": "1.14.0", + "sharp": "^0.32.0" + }, + "optionalDependencies": { + "onnxruntime-node": "1.14.0" + } + }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "license": "Apache-2.0" + }, + "node_modules/bare-events": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", + "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/bare-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.6.tgz", + "integrity": "sha512-25RsLF33BqooOEFNdMcEhMpJy8EoR88zSMrnOQOaM3USnOK2VmaJ1uaQEwPA6AQjrv1lXChScosN6CzbwbO9OQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", + "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", + "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "license": "MIT" + }, + "node_modules/flatbuffers": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", + "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==", + "license": "SEE LICENSE IN LICENSE.txt" + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, + "node_modules/guid-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", + "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==", + "license": "ISC" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" + }, + "node_modules/node-abi": { + "version": "3.75.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", + "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onnx-proto": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz", + "integrity": "sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA==", + "license": "MIT", + "dependencies": { + "protobufjs": "^6.8.8" + } + }, + "node_modules/onnxruntime-common": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.14.0.tgz", + "integrity": "sha512-3LJpegM2iMNRX2wUmtYfeX/ytfOzNwAWKSq1HbRrKc9+uqG/FsEA0bbKZl1btQeZaXhC26l44NWpNUeXPII7Ew==", + "license": "MIT" + }, + "node_modules/onnxruntime-node": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.14.0.tgz", + "integrity": "sha512-5ba7TWomIV/9b6NH/1x/8QEeowsb+jBEvFzU6z0T4mNsFwdPqXeFUM7uxC6QeSRkEbWu3qEB0VMjrvzN/0S9+w==", + "license": "MIT", + "optional": true, + "os": [ + "win32", + "darwin", + "linux" + ], + "dependencies": { + "onnxruntime-common": "~1.14.0" + } + }, + "node_modules/onnxruntime-web": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.14.0.tgz", + "integrity": "sha512-Kcqf43UMfW8mCydVGcX9OMXI2VN17c0p6XvR7IPSZzBf/6lteBzXHvcEVWDPmCKuGombl997HgLqj91F11DzXw==", + "license": "MIT", + "dependencies": { + "flatbuffers": "^1.12.0", + "guid-typescript": "^1.0.9", + "long": "^4.0.0", + "onnx-proto": "^4.0.4", + "onnxruntime-common": "~1.14.0", + "platform": "^1.3.6" + } + }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "license": "MIT" + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", + "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/prebuild-install/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/redis": { + "resolved": "../../../../../packages/redis", + "link": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/streamx": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz", + "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==", + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar-fs": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.0.tgz", + "integrity": "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + } + } +} diff --git a/doctests/package.json b/doctests/package.json new file mode 100644 index 00000000000..ee07eb44fb8 --- /dev/null +++ b/doctests/package.json @@ -0,0 +1,12 @@ +{ + "name": "node-redis-doctests", + "version": "1.0.0", + "description": "Code examples for redis.io", + "main": "index.js", + "private": true, + "type": "module", + "dependencies": { + "redis": "file:/packages/redis", + "@xenova/transformers": "^2.17.2" + } +} diff --git a/doctests/query-agg.js b/doctests/query-agg.js new file mode 100644 index 00000000000..82d378b86b2 --- /dev/null +++ b/doctests/query-agg.js @@ -0,0 +1,139 @@ +// EXAMPLE: query_agg +// HIDE_START +import assert from 'node:assert'; +import fs from 'node:fs'; +import { createClient } from 'redis'; +import { SCHEMA_FIELD_TYPE, FT_AGGREGATE_STEPS, FT_AGGREGATE_GROUP_BY_REDUCERS } from '@redis/search'; + +const client = createClient(); + +await client.connect().catch(console.error); + +// create index +await client.ft.create('idx:bicycle', { + '$.condition': { + type: SCHEMA_FIELD_TYPE.TAG, + AS: 'condition' + }, + '$.price': { + type: SCHEMA_FIELD_TYPE.NUMERIC, + AS: 'price' + } +}, { + ON: 'JSON', + PREFIX: 'bicycle:' +}) + +// load data +const bicycles = JSON.parse(fs.readFileSync('data/query_em.json', 'utf8')); + +await Promise.all( + bicycles.map((bicycle, bid) => { + return client.json.set(`bicycle:${bid}`, '$', bicycle); + }) +); +// HIDE_END + +// STEP_START agg1 +const res1 = await client.ft.aggregate('idx:bicycle', '@condition:{new}', { + LOAD: ['__key', 'price'], + APPLY: { + expression: '@price - (@price * 0.1)', + AS: 'discounted' + } +}); + +console.log(res1.results.length); // >>> 5 +console.log(res1.results); // >>> +//[ +// [Object: null prototype] { __key: 'bicycle:0', price: '270' }, +// [Object: null prototype] { __key: 'bicycle:5', price: '810' }, +// [Object: null prototype] { __key: 'bicycle:6', price: '2300' }, +// [Object: null prototype] { __key: 'bicycle:7', price: '430' }, +// [Object: null prototype] { __key: 'bicycle:8', price: '1200' } +//] +// REMOVE_START +assert.strictEqual(res1.results.length, 5); +// REMOVE_END +// STEP_END + +// STEP_START agg2 +const res2 = await client.ft.aggregate('idx:bicycle', '*', { + LOAD: ['@price'], + STEPS: [{ + type: FT_AGGREGATE_STEPS.APPLY, + expression: '@price<1000', + AS: 'price_category' + },{ + type: FT_AGGREGATE_STEPS.GROUPBY, + properties: '@condition', + REDUCE:[{ + type: FT_AGGREGATE_GROUP_BY_REDUCERS.SUM, + property: '@price_category', + AS: 'num_affordable' + }] + }] +}); +console.log(res2.results.length); // >>> 3 +console.log(res2.results); // >>> +//[[Object: null prototype] { condition: 'refurbished', num_affordable: '1' }, +// [Object: null prototype] { condition: 'used', num_affordable: '1' }, +// [Object: null prototype] { condition: 'new', num_affordable: '3' } +//] +// REMOVE_START +assert.strictEqual(res2.results.length, 3); +// REMOVE_END +// STEP_END + +// STEP_START agg3 +const res3 = await client.ft.aggregate('idx:bicycle', '*', { + STEPS: [{ + type: FT_AGGREGATE_STEPS.APPLY, + expression: "'bicycle'", + AS: 'type' + }, { + type: FT_AGGREGATE_STEPS.GROUPBY, + properties: '@type', + REDUCE: [{ + type: FT_AGGREGATE_GROUP_BY_REDUCERS.COUNT, + property: null, + AS: 'num_total' + }] + }] +}); +console.log(res3.results.length); // >>> 1 +console.log(res3.results); // >>> +//[ [Object: null prototype] { type: 'bicycle', num_total: '10' } ] +// REMOVE_START +assert.strictEqual(res3.results.length, 1); +// REMOVE_END +// STEP_END + +// STEP_START agg4 +const res4 = await client.ft.aggregate('idx:bicycle', '*', { + LOAD: ['__key'], + STEPS: [{ + type: FT_AGGREGATE_STEPS.GROUPBY, + properties: '@condition', + REDUCE: [{ + type: FT_AGGREGATE_GROUP_BY_REDUCERS.TOLIST, + property: '__key', + AS: 'bicycles' + }] + }] +}); +console.log(res4.results.length); // >>> 3 +console.log(res4.results); // >>> +//[[Object: null prototype] {condition: 'refurbished', bicycles: [ 'bicycle:9' ]}, +// [Object: null prototype] {condition: 'used', bicycles: [ 'bicycle:1', 'bicycle:2', 'bicycle:3', 'bicycle:4' ]}, +// [Object: null prototype] {condition: 'new', bicycles: [ 'bicycle:5', 'bicycle:6', 'bicycle:7', 'bicycle:0', 'bicycle:8' ]}] +// REMOVE_START +assert.strictEqual(res4.results.length, 3); +// REMOVE_END +// STEP_END + +// REMOVE_START +// destroy index and data +await client.ft.dropIndex('idx:bicycle', { DD: true }); +await client.close(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/query-combined.js b/doctests/query-combined.js new file mode 100644 index 00000000000..a2ad8d43c93 --- /dev/null +++ b/doctests/query-combined.js @@ -0,0 +1,191 @@ +// EXAMPLE: query_combined +// HIDE_START +import assert from 'node:assert'; +import fs from 'node:fs'; +import { createClient } from 'redis'; +import { SCHEMA_FIELD_TYPE, SCHEMA_VECTOR_FIELD_ALGORITHM } from '@redis/search'; +import { pipeline } from '@xenova/transformers'; + +function float32Buffer(arr) { + const floatArray = new Float32Array(arr); + const float32Buffer = Buffer.from(floatArray.buffer); + return float32Buffer; +} + +async function embedText(sentence) { + let modelName = 'Xenova/all-MiniLM-L6-v2'; + let pipe = await pipeline('feature-extraction', modelName); + + let vectorOutput = await pipe(sentence, { + pooling: 'mean', + normalize: true, + }); + + if (vectorOutput == null) { + throw new Error('vectorOutput is undefined'); + } + + const embedding = Object.values(vectorOutput.data); + + return embedding; +} + +let vector_query = float32Buffer(await embedText('That is a very happy person')); + +const client = createClient(); +await client.connect().catch(console.error); + +// create index +await client.ft.create('idx:bicycle', { + '$.description': { + type: SCHEMA_FIELD_TYPE.TEXT, + AS: 'description' + }, + '$.condition': { + type: SCHEMA_FIELD_TYPE.TAG, + AS: 'condition' + }, + '$.price': { + type: SCHEMA_FIELD_TYPE.NUMERIC, + AS: 'price' + }, + '$.description_embeddings': { + type: SCHEMA_FIELD_TYPE.VECTOR, + TYPE: 'FLOAT32', + ALGORITHM: SCHEMA_VECTOR_FIELD_ALGORITHM.FLAT, + DIM: 384, + DISTANCE_METRIC: 'COSINE', + AS: 'vector', + } +}, { + ON: 'JSON', + PREFIX: 'bicycle:' +}); + +// load data +const bicycles = JSON.parse(fs.readFileSync('data/query_vector.json', 'utf8')); + +await Promise.all( + bicycles.map((bicycle, bid) => { + return client.json.set(`bicycle:${bid}`, '$', bicycle); + }) +); +// HIDE_END + +// STEP_START combined1 +const res1 = await client.ft.search('idx:bicycle', '@price:[500 1000] @condition:{new}'); +console.log(res1.total); // >>> 1 +console.log(res1); // >>> +//{ +// total: 1, +// documents: [ { id: 'bicycle:5', value: [Object: null prototype] } ] +//} +// REMOVE_START +assert.strictEqual(res1.total, 1); +// REMOVE_END +// STEP_END + +// STEP_START combined2 +const res2 = await client.ft.search('idx:bicycle', 'kids @price:[500 1000] @condition:{used}'); +console.log(res2.total); // >>> 1 +console.log(res2); // >>> +// { +// total: 1, +// documents: [ { id: 'bicycle:2', value: [Object: null prototype] } ] +// } +// REMOVE_START +assert.strictEqual(res2.total, 1); +// REMOVE_END +// STEP_END + +// STEP_START combined3 +const res3 = await client.ft.search('idx:bicycle', '(kids | small) @condition:{used}'); +console.log(res3.total); // >>> 2 +console.log(res3); // >>> +//{ +// total: 2, +// documents: [ +// { id: 'bicycle:2', value: [Object: null prototype] }, +// { id: 'bicycle:1', value: [Object: null prototype] } +// ] +//} +// REMOVE_START +assert.strictEqual(res3.total, 2); +// REMOVE_END +// STEP_END + +// STEP_START combined4 +const res4 = await client.ft.search('idx:bicycle', '@description:(kids | small) @condition:{used}'); +console.log(res4.total); // >>> 2 +console.log(res4); // >>> +//{ +// total: 2, +// documents: [ +// { id: 'bicycle:2', value: [Object: null prototype] }, +// { id: 'bicycle:1', value: [Object: null prototype] } +// ] +//} +// REMOVE_START +assert.strictEqual(res4.total, 2); +// REMOVE_END +// STEP_END + +// STEP_START combined5 +const res5 = await client.ft.search('idx:bicycle', '@description:(kids | small) @condition:{new | used}'); +console.log(res5.total); // >>> 3 +console.log(res5); // >>> +//{ +// total: 3, +// documents: [ +// { id: 'bicycle:1', value: [Object: null prototype] }, +// { id: 'bicycle:0', value: [Object: null prototype] }, +// { id: 'bicycle:2', value: [Object: null prototype] } +// ] +//} +// REMOVE_START +assert.strictEqual(res5.total, 3); +// REMOVE_END +// STEP_END + +// STEP_START combined6 +const res6 = await client.ft.search('idx:bicycle', '@price:[500 1000] -@condition:{new}'); +console.log(res6.total); // >>> 2 +console.log(res6); // >>> +//{ +// total: 2, +// documents: [ +// { id: 'bicycle:2', value: [Object: null prototype] }, +// { id: 'bicycle:9', value: [Object: null prototype] } +// ] +//} +// REMOVE_START +assert.strictEqual(res6.total, 2); +// REMOVE_END +// STEP_END + +// STEP_START combined7 +const res7 = await client.ft.search('idx:bicycle', + '(@price:[500 1000] -@condition:{new})=>[KNN 3 @vector $query_vector]', { + PARAMS: { query_vector: vector_query }, + DIALECT: 2 + } +); +console.log(res7.total); // >>> 2 +console.log(res7); // >>> +//{ +// total: 2, +// documents: [ +// { id: 'bicycle:2', value: [Object: null prototype] }, +// { id: 'bicycle:9', value: [Object: null prototype] } +// ] +//} +// REMOVE_START +assert.strictEqual(res7.total, 2); +// REMOVE_END +// STEP_END + +// REMOVE_START +// destroy index and data +await client.ft.dropIndex('idx:bicycle', { DD: true }); +await client.close(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/query-em.js b/doctests/query-em.js new file mode 100644 index 00000000000..9b5782e09ce --- /dev/null +++ b/doctests/query-em.js @@ -0,0 +1,121 @@ +// EXAMPLE: query_em +// HIDE_START +import assert from 'node:assert'; +import fs from 'node:fs'; +import { createClient, SCHEMA_FIELD_TYPE } from 'redis'; + +const client = createClient(); + +await client.connect().catch(console.error); + +// create index +await client.ft.create('idx:bicycle', { + '$.description': { + type: SCHEMA_FIELD_TYPE.TEXT, + AS: 'description' + }, + '$.price': { + type: SCHEMA_FIELD_TYPE.NUMERIC, + AS: 'price' + }, + '$.condition': { + type: SCHEMA_FIELD_TYPE.TAG, + AS: 'condition' + } +}, { + ON: 'JSON', + PREFIX: 'bicycle:' +}) + +// load data +const bicycles = JSON.parse(fs.readFileSync('data/query_em.json', 'utf8')); + +await Promise.all( + bicycles.map((bicycle, bid) => { + return client.json.set(`bicycle:${bid}`, '$', bicycle); + }) +); +// HIDE_END + +// STEP_START em1 +const res1 = await client.ft.search('idx:bicycle', '@price:[270 270]'); +console.log(res1.total); // >>> 1 +// REMOVE_START +assert.strictEqual(res1.total, 1); +// REMOVE_END + +try { + const res2 = await client.ft.search('idx:bicycle', '@price:[270]'); + console.log(res2.total); // >>> 1 + assert.strictEqual(res2.total, 1); +} catch (err) { + console.log("'@price:[270]' syntax not yet supported."); +} + +try { + const res3 = await client.ft.search('idx:bicycle', '@price==270'); + console.log(res3.total); // >>> 1 + assert.strictEqual(res3.total, 1); +} catch (err) { + console.log("'@price==270' syntax not yet supported."); +} + +// FILTER is not supported +// const res4 = await client.ft.search('idx:bicycle', '*', { +// FILTER: { +// field: 'price', +// min: 270, +// max: 270, +// } +// }); +// console.log(res4.total); // >>> 1 +// REMOVE_START +// assert.strictEqual(res4.total, 10); +// REMOVE_END +// STEP_END + +// STEP_START em2 +const res5 = await client.ft.search('idx:bicycle', '@condition:{new}'); +console.log(res5.total); // >>> 5 +// REMOVE_START +assert.strictEqual(res5.total, 5); +// REMOVE_END +// STEP_END + +// STEP_START em3 +await client.ft.create('idx:email', { + '$.email': { + type: SCHEMA_FIELD_TYPE.TAG, + AS: 'email' + } +}, { + ON: 'JSON', + PREFIX: 'key:' +}) + +await client.json.set('key:1', '$', { email: 'test@redis.com' }); + +try { + const res6 = await client.ft.search('idx:email', 'test@redis.com', { DIALECT: 2 }); + console.log(res6); +} catch (err) { + console.log("'test@redis.com' syntax not yet supported."); +} +// REMOVE_START +await client.ft.dropIndex('idx:email', { DD: true }); +// REMOVE_END +// STEP_END + +// STEP_START em4 +const res7 = await client.ft.search('idx:bicycle', '@description:"rough terrain"'); +console.log(res7.total); // >>> 1 (Result{1 total, docs: [Document {'id': 'bicycle:8'...) +// REMOVE_START +assert.strictEqual(res7.total, 1); +// REMOVE_END +// STEP_END + +// REMOVE_START +// destroy index and data +await client.ft.dropIndex('idx:bicycle', { DD: true }); +await client.close(); +// REMOVE_END diff --git a/doctests/query-ft.js b/doctests/query-ft.js new file mode 100644 index 00000000000..a70b2ea3f5d --- /dev/null +++ b/doctests/query-ft.js @@ -0,0 +1,84 @@ +// EXAMPLE: query_ft +// HIDE_START +import assert from 'node:assert'; +import fs from 'node:fs'; +import { createClient, SCHEMA_FIELD_TYPE } from 'redis'; + +const client = createClient(); + +await client.connect().catch(console.error); + +// create index +await client.ft.create('idx:bicycle', { + '$.model': { + type: SCHEMA_FIELD_TYPE.TEXT, + AS: 'model' + }, + '$.brand': { + type: SCHEMA_FIELD_TYPE.TEXT, + AS: 'brand' + }, + '$.description': { + type: SCHEMA_FIELD_TYPE.TEXT, + AS: 'description' + } +}, { + ON: 'JSON', + PREFIX: 'bicycle:' +}) + +// load data +const bicycles = JSON.parse(fs.readFileSync('data/query_em.json', 'utf8')); + +await Promise.all( + bicycles.map((bicycle, bid) => { + return client.json.set(`bicycle:${bid}`, '$', bicycle); + }) +); +// HIDE_END + +// STEP_START ft1 +const res1 = await client.ft.search('idx:bicycle', '@description: kids'); +console.log(res1.total); // >>> 2 +// REMOVE_START +assert.strictEqual(res1.total, 2); +// REMOVE_END +// STEP_END + +// STEP_START ft2 +const res2 = await client.ft.search('idx:bicycle', '@model: ka*'); +console.log(res2.total); // >>> 1 +// REMOVE_START +assert.strictEqual(res2.total, 1); +// REMOVE_END +// STEP_END + +// STEP_START ft3 +const res3 = await client.ft.search('idx:bicycle', '@brand: *bikes'); +console.log(res3.total); // >>> 2 +// REMOVE_START +assert.strictEqual(res3.total, 2); +// REMOVE_END +// STEP_END + +// STEP_START ft4 +const res4 = await client.ft.search('idx:bicycle', '%optamized%'); +console.log(res4); // >>> { total: 1, documents: [ { id: 'bicycle:3', value: [Object: null prototype] } ]} +// REMOVE_START +assert.strictEqual(res4.total, 1); +// REMOVE_END +// STEP_END + +// STEP_START ft5 +const res5 = await client.ft.search('idx:bicycle', '%%optamised%%'); +console.log(res5); // >>> { total: 1, documents: [ { id: 'bicycle:3', value: [Object: null prototype] } ]} +// REMOVE_START +assert.strictEqual(res5.total, 1); +// REMOVE_END +// STEP_END + +// REMOVE_START +// destroy index and data +await client.ft.dropIndex('idx:bicycle', { DD: true }); +await client.close(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/query-geo.js b/doctests/query-geo.js new file mode 100644 index 00000000000..41ef2141eb8 --- /dev/null +++ b/doctests/query-geo.js @@ -0,0 +1,82 @@ +// EXAMPLE: query_geo +// HIDE_START +import assert from 'node:assert'; +import fs from 'node:fs'; +import { createClient } from 'redis'; +import { SCHEMA_FIELD_TYPE } from '@redis/search'; + +const client = createClient(); + +await client.connect().catch(console.error); + +// create index +await client.ft.create('idx:bicycle', { + '$.store_location': { + type: SCHEMA_FIELD_TYPE.GEO, + AS: 'store_location' + }, + '$.pickup_zone': { + type: SCHEMA_FIELD_TYPE.GEOSHAPE, + AS: 'pickup_zone' + } +}, { + ON: 'JSON', + PREFIX: 'bicycle:' +}) + +// load data +const bicycles = JSON.parse(fs.readFileSync('data/query_em.json', 'utf8')); + +await Promise.all( + bicycles.map((bicycle, bid) => { + return client.json.set(`bicycle:${bid}`, '$', bicycle); + }) +); +// HIDE_END + +// STEP_START geo1 +const res1= await client.ft.search('idx:bicycle', '@store_location:[-0.1778 51.5524 20 mi]'); +console.log(res1.total); // >>> 1 +console.log(res1); // >>> {total: 1, documents: [ { id: 'bicycle:5', value: [Object: null prototype] } ]} +// REMOVE_START +assert.strictEqual(res1.total, 1); +// REMOVE_END +// STEP_END + +// STEP_START geo2 +const params_dict_geo2 = { bike: 'POINT(-0.1278 51.5074)' }; +const q_geo2 = '@pickup_zone:[CONTAINS $bike]'; +const res2 = await client.ft.search('idx:bicycle', q_geo2, { PARAMS: params_dict_geo2, DIALECT: 3 }); +console.log(res2.total); // >>> 1 +console.log(res2); // >>> {total: 1, documents: [ { id: 'bicycle:5', value: [Object: null prototype] } ]} +// REMOVE_START +assert.strictEqual(res2.total, 1); +// REMOVE_END +// STEP_END + +// STEP_START geo3 +const params_dict_geo3 = { europe: 'POLYGON((-25 35, 40 35, 40 70, -25 70, -25 35))' }; +const q_geo3 = '@pickup_zone:[WITHIN $europe]'; +const res3 = await client.ft.search('idx:bicycle', q_geo3, { PARAMS: params_dict_geo3, DIALECT: 3 }); +console.log(res3.total); // >>> 5 +console.log(res3); // >>> +// { +// total: 5, +// documents: [ +// { id: 'bicycle:5', value: [Object: null prototype] }, +// { id: 'bicycle:6', value: [Object: null prototype] }, +// { id: 'bicycle:7', value: [Object: null prototype] }, +// { id: 'bicycle:8', value: [Object: null prototype] }, +// { id: 'bicycle:9', value: [Object: null prototype] } +// ] +// } +// REMOVE_START +assert.strictEqual(res3.total, 5); +// REMOVE_END +// STEP_END + +// REMOVE_START +// destroy index and data +await client.ft.dropIndex('idx:bicycle', { DD: true }); +await client.close(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/query-range.js b/doctests/query-range.js new file mode 100644 index 00000000000..29b269e37b5 --- /dev/null +++ b/doctests/query-range.js @@ -0,0 +1,98 @@ +// EXAMPLE: query_range +// HIDE_START +import assert from 'node:assert'; +import fs from 'node:fs'; +import { createClient, SCHEMA_FIELD_TYPE,} from 'redis'; + +const client = createClient(); + +await client.connect().catch(console.error); + +// create index +await client.ft.create('idx:bicycle', { + '$.description': { + type: SCHEMA_FIELD_TYPE.TEXT, + AS: 'description' + }, + '$.price': { + type: SCHEMA_FIELD_TYPE.NUMERIC, + AS: 'price' + }, + '$.condition': { + type: SCHEMA_FIELD_TYPE.TAG, + AS: 'condition' + } +}, { + ON: 'JSON', + PREFIX: 'bicycle:' +}) + +// load data +const bicycles = JSON.parse(fs.readFileSync('data/query_em.json', 'utf8')); + +await Promise.all( + bicycles.map((bicycle, bid) => { + return client.json.set(`bicycle:${bid}`, '$', bicycle); + }) +); +// HIDE_END + +// STEP_START range1 +const res1 = await client.ft.search('idx:bicycle', '@price:[500 1000]'); +console.log(res1.total); // >>> 3 +// REMOVE_START +assert.strictEqual(res1.total, 3); +// REMOVE_END +// STEP_END + +// STEP_START range2 +// FILTER is not supported +// const res2 = await client.ft.search('idx:bicycle', '*', { +// FILTER: { +// field: 'price', +// min: 500, +// max: 1000, +// } +// }); +// console.log(res2.total); // >>> 3 +// REMOVE_START +// assert.strictEqual(res2.total, 3); +// REMOVE_END +// STEP_END + +// STEP_START range3 +// FILTER is not supported +// const res3 = await client.ft.search('idx:bicycle', '*', { +// FILTER: { +// field: 'price', +// min: '(1000', +// max: '+inf, +// } +// }); +// console.log(res3.total); // >>> 5 +// REMOVE_START +// assert.strictEqual(res3.total, 5); +// REMOVE_END +// STEP_END + +// STEP_START range4 +const res4 = await client.ft.search( + 'idx:bicycle', + '@price:[-inf 2000]', + { + SORTBY: 'price', + LIMIT: { from: 0, size: 5 } + } +); +console.log(res4.total); // >>> 7 +console.log(res4); // >>> { total: 7, documents: [ { id: 'bicycle:0', value: [Object: null prototype] }, { id: 'bicycle:7', value: [Object: null prototype] }, { id: 'bicycle:5', value: [Object: null prototype] }, { id: 'bicycle:2', value: [Object: null prototype] }, { id: 'bicycle:9', value: [Object: null prototype] } ] } +// REMOVE_START +assert.strictEqual(res4.total, 7); +// REMOVE_END +// STEP_END + +// REMOVE_START +// destroy index and data +await client.ft.dropIndex('idx:bicycle', { DD: true }); +await client.close(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/query-vector.js b/doctests/query-vector.js new file mode 100644 index 00000000000..91ee63120d3 --- /dev/null +++ b/doctests/query-vector.js @@ -0,0 +1,110 @@ +// EXAMPLE: query_vector +// HIDE_START +import assert from 'node:assert'; +import fs from 'node:fs'; +import { createClient } from 'redis'; +import { SCHEMA_FIELD_TYPE, SCHEMA_VECTOR_FIELD_ALGORITHM } from '@redis/search'; +import { pipeline } from '@xenova/transformers'; + +function float32Buffer(arr) { + const floatArray = new Float32Array(arr); + const float32Buffer = Buffer.from(floatArray.buffer); + return float32Buffer; +} + +async function embedText(sentence) { + let modelName = 'Xenova/all-MiniLM-L6-v2'; + let pipe = await pipeline('feature-extraction', modelName); + + let vectorOutput = await pipe(sentence, { + pooling: 'mean', + normalize: true, + }); + + const embedding = Object.values(vectorOutput?.data); + + return embedding; +} + +const vector_query = float32Buffer(await embedText('That is a very happy person')); + +const client = createClient(); +await client.connect().catch(console.error); + +// create index +await client.ft.create('idx:bicycle', { + '$.description': { + type: SCHEMA_FIELD_TYPE.TEXT, + AS: 'description' + }, + '$.description_embeddings': { + type: SCHEMA_FIELD_TYPE.VECTOR, + TYPE: 'FLOAT32', + ALGORITHM: SCHEMA_VECTOR_FIELD_ALGORITHM.FLAT, + DIM: 384, + DISTANCE_METRIC: 'COSINE', + AS: 'vector' + } +}, { + ON: 'JSON', + PREFIX: 'bicycle:' +}); + +// load data +const bicycles = JSON.parse(fs.readFileSync('data/query_vector.json', 'utf8')); + +await Promise.all( + bicycles.map((bicycle, bid) => { + return client.json.set(`bicycle:${bid}`, '$', bicycle); + }) +); +// HIDE_END + +// STEP_START vector1 +const res1 = await client.ft.search('idx:bicycle', + '*=>[KNN 3 @vector $query_vector AS score]', { + PARAMS: { query_vector: vector_query }, + RETURN: ['description'], + DIALECT: 2 + } +); +console.log(res1.total); // >>> 3 +console.log(res1); // >>> +//{ +// total: 3, +// documents: [ +// { id: 'bicycle:0', value: [Object: null prototype] {} }, +// { id: 'bicycle:2', value: [Object: null prototype] {} }, +// { id: 'bicycle:9', value: [Object: null prototype] {} } +// ] +//} +// REMOVE_START +assert.strictEqual(res1.total, 3); +// REMOVE_END +// STEP_END + +// STEP_START vector2 +const res2 = await client.ft.search('idx:bicycle', + '@vector:[VECTOR_RANGE 0.9 $query_vector]=>{$YIELD_DISTANCE_AS: vector_dist}', { + PARAMS: { query_vector: vector_query }, + SORTBY: 'vector_dist', + RETURN: ['vector_dist', 'description'], + DIALECT: 2 + } +); +console.log(res2.total); // >>> 1 +console.log(res2); // >>> +//{ +// total: 1, +// documents: [ { id: 'bicycle:0', value: [Object: null prototype] } ] +//} +// REMOVE_START +assert.strictEqual(res2.total, 1); +// REMOVE_END +// STEP_END + +// REMOVE_START +// destroy index and data +await client.ft.dropIndex('idx:bicycle', { DD: true }); +await client.close(); +// REMOVE_END \ No newline at end of file diff --git a/doctests/run_examples.sh b/doctests/run_examples.sh new file mode 100755 index 00000000000..ee7b50dc69a --- /dev/null +++ b/doctests/run_examples.sh @@ -0,0 +1,15 @@ +#!/bin/sh + + +basepath=`readlink -f $1` +if [ $? -ne 0 ]; then +basepath=`readlink -f $(dirname $0)` +fi +echo "No path specified, using ${basepath}" + +set -e +cd ${basepath} +for i in `ls ${basepath}/*.js`; do + redis-cli flushdb + node $i +done \ No newline at end of file diff --git a/doctests/search-quickstart.js b/doctests/search-quickstart.js new file mode 100644 index 00000000000..ec3f65a5e3a --- /dev/null +++ b/doctests/search-quickstart.js @@ -0,0 +1,231 @@ +// EXAMPLE: search_quickstart +// REMOVE_START +import assert from 'assert'; +// REMOVE_END +// HIDE_START +import { createClient, SCHEMA_FIELD_TYPE } from 'redis'; +// HIDE_END +// STEP_START connect +const client = createClient(); +client.on('error', err => console.log('Redis Client Error', err)); + +await client.connect(); +// STEP_END + +// STEP_START data_sample +const bicycle1 = { + brand: 'Velorim', + model: 'Jigger', + price: 270, + description: + 'Small and powerful, the Jigger is the best ' + + 'ride for the smallest of tikes! This is the tiniest kids\u2019 ' + + 'pedal bike on the market available without a coaster brake, the ' + + 'Jigger is the vehicle of choice for the rare tenacious little' + + 'rider raring to go.', + condition: 'new' +}; +// STEP_END +const bicycles = [ + bicycle1, + { + brand: 'Bicyk', + model: 'Hillcraft', + price: 1200, + description: 'Kids want to ride with as little weight as possible. Especially on an incline! They may be at the age when a 27.5\" wheel bike is just too clumsy coming off a 24\" bike. The Hillcraft 26 is just the solution they need!', + condition: 'used' + }, + { + brand: 'Nord', + model: 'Chook air 5', + price: 815, + description: 'The Chook Air 5 gives kids aged six years and older a durable and uberlight mountain bike for their first experience on tracks and easy cruising through forests and fields. The lower top tube makes it easy to mount and dismount in any situation, giving your kids greater safety on the trails.', + condition: 'used' + }, + { + brand: 'Eva', + model: 'Eva 291', + price: 3400, + description: 'The sister company to Nord, Eva launched in 2005 as the first and only women-dedicated bicycle brand. Designed by women for women, allEva bikes are optimized for the feminine physique using analytics from a body metrics database. If you like 29ers, try the Eva 291. It\u2019s a brand new bike for 2022.. This full-suspension, cross-country ride has been designed for velocity. The 291 has 100mm of front and rear travel, a superlight aluminum frame and fast-rolling 29-inch wheels. Yippee!', + condition: 'used' + }, + { + brand: 'Noka Bikes', + model: 'Kahuna', + price: 3200, + description: 'Whether you want to try your hand at XC racing or are looking for a lively trail bike that\'s just as inspiring on the climbs as it is over rougher ground, the Wilder is one heck of a bike built specifically for short women. Both the frames and components have been tweaked to include a women\u2019s saddle, different bars and unique colourway.', + condition: 'used' + }, + { + brand: 'Breakout', + model: 'XBN 2.1 Alloy', + price: 810, + description: 'The XBN 2.1 Alloy is our entry-level road bike \u2013 but that\u2019s not to say that it\u2019s a basic machine. With an internal weld aluminium frame, a full carbon fork, and the slick-shifting Claris gears from Shimano\u2019s, this is a bike which doesn\u2019t break the bank and delivers craved performance.', + condition: 'new' + }, + { + brand: 'ScramBikes', + model: 'WattBike', + price: 2300, + description: 'The WattBike is the best e-bike for people who still feel young at heart. It has a Bafang 1000W mid-drive system and a 48V 17.5AH Samsung Lithium-Ion battery, allowing you to ride for more than 60 miles on one charge. It\u2019s great for tackling hilly terrain or if you just fancy a more leisurely ride. With three working modes, you can choose between E-bike, assisted bicycle, and normal bike modes.', + condition: 'new' + }, + { + brand: 'Peaknetic', + model: 'Secto', + price: 430, + description: 'If you struggle with stiff fingers or a kinked neck or back after a few minutes on the road, this lightweight, aluminum bike alleviates those issues and allows you to enjoy the ride. From the ergonomic grips to the lumbar-supporting seat position, the Roll Low-Entry offers incredible comfort. The rear-inclined seat tube facilitates stability by allowing you to put a foot on the ground to balance at a stop, and the low step-over frame makes it accessible for all ability and mobility levels. The saddle is very soft, with a wide back to support your hip joints and a cutout in the center to redistribute that pressure. Rim brakes deliver satisfactory braking control, and the wide tires provide a smooth, stable ride on paved roads and gravel. Rack and fender mounts facilitate setting up the Roll Low-Entry as your preferred commuter, and the BMX-like handlebar offers space for mounting a flashlight, bell, or phone holder.', + condition: 'new' + }, + { + brand: 'nHill', + model: 'Summit', + price: 1200, + description: 'This budget mountain bike from nHill performs well both on bike paths and on the trail. The fork with 100mm of travel absorbs rough terrain. Fat Kenda Booster tires give you grip in corners and on wet trails. The Shimano Tourney drivetrain offered enough gears for finding a comfortable pace to ride uphill, and the Tektro hydraulic disc brakes break smoothly. Whether you want an affordable bike that you can take to work, but also take trail in mountains on the weekends or you\u2019re just after a stable, comfortable ride for the bike path, the Summit gives a good value for money.', + condition: 'new' + }, + { + model: 'ThrillCycle', + brand: 'BikeShind', + price: 815, + description: 'An artsy, retro-inspired bicycle that\u2019s as functional as it is pretty: The ThrillCycle steel frame offers a smooth ride. A 9-speed drivetrain has enough gears for coasting in the city, but we wouldn\u2019t suggest taking it to the mountains. Fenders protect you from mud, and a rear basket lets you transport groceries, flowers and books. The ThrillCycle comes with a limited lifetime warranty, so this little guy will last you long past graduation.', + condition: 'refurbished' + } +]; +// STEP_START create_index +const schema = { + '$.brand': { + type: SCHEMA_FIELD_TYPE.TEXT, + SORTABLE: true, + AS: 'brand' + }, + '$.model': { + type: SCHEMA_FIELD_TYPE.TEXT, + AS: 'model' + }, + '$.description': { + type: SCHEMA_FIELD_TYPE.TEXT, + AS: 'description' + }, + '$.price': { + type: SCHEMA_FIELD_TYPE.NUMERIC, + AS: 'price' + }, + '$.condition': { + type: SCHEMA_FIELD_TYPE.TAG, + AS: 'condition' + } +}; + +try { + await client.ft.create('idx:bicycle', schema, { + ON: 'JSON', + PREFIX: 'bicycle:' + }); +} catch (e) { + if (e.message === 'Index already exists') { + console.log('Index exists already, skipped creation.'); + } else { + // Something went wrong, perhaps RediSearch isn't installed... + console.error(e); + process.exit(1); + } +} +// STEP_END + +// STEP_START add_documents +await Promise.all( + bicycles.map((bicycle, i) => client.json.set(`bicycle:${i}`, '$', bicycle)) +); +// STEP_END + +// STEP_START wildcard_query +let result = await client.ft.search('idx:bicycle', '*', { + LIMIT: { + from: 0, + size: 10 + } +}); + +console.log(JSON.stringify(result, null, 2)); + +/* +{ + "total": 10, + "documents": ... +} +*/ +// STEP_END + +// REMOVE_START +assert.equal(result.documents[0].id, 'bicycle:0'); +// REMOVE_END + +// STEP_START query_single_term +result = await client.ft.search( + 'idx:bicycle', + '@model:Jigger', + { + LIMIT: { + from: 0, + size: 10 + } +}); + +console.log(JSON.stringify(result, null, 2)); +/* +{ + "total": 1, + "documents": [{ + "id": "bicycle:0", + "value": { + "brand": "Velorim", + "model": "Jigger", + "price": 270, + "description": "Small and powerful, the Jigger is the best ride for the smallest of tikes! This is the tiniest kids’ pedal bike on the market available without a coaster brake, the Jigger is the vehicle of choice for the rare tenacious little rider raring to go.", + "condition": "new" + } + }] +} + */ +// STEP_END +// REMOVE_START +assert.equal(result.documents[0].id, 'bicycle:0'); +// REMOVE_END + +// STEP_START query_exact_matching +result = await client.ft.search( + 'idx:bicycle', + '@brand:"Noka Bikes"', + { + LIMIT: { + from: 0, + size: 10 + } + } +); + +console.log(JSON.stringify(result, null, 2)); + +/* +{ + "total": 1, + "documents": [{ + "id": "bicycle:4", + "value": { + "brand": "Noka Bikes", + "model": "Kahuna", + "price": 3200, + "description": "Whether you want to try your hand at XC racing or are looking for a lively trail bike that's just as inspiring on the climbs as it is over rougher ground, the Wilder is one heck of a bike built specifically for short women. Both the frames and components have been tweaked to include a women’s saddle, different bars and unique colourway.", + "condition": "used" + } + }] +} +*/ +// STEP_END + +// REMOVE_START +assert.equal(result.documents[0].id, 'bicycle:4'); +// REMOVE END + +await client.close(); diff --git a/doctests/string-set-get-example.js b/doctests/string-set-get-example.js new file mode 100644 index 00000000000..b9be382285e --- /dev/null +++ b/doctests/string-set-get-example.js @@ -0,0 +1,27 @@ +// EXAMPLE: set_and_get +// REMOVE_START +import assert from "node:assert"; +// REMOVE_END + +// HIDE_START +import { createClient } from 'redis'; + +const client = createClient(); + +client.on('error', err => console.log('Redis Client Error', err)); + +await client.connect().catch(console.error); + +// HIDE_END +await client.set('bike:1', 'Process 134'); +const value = await client.get('bike:1'); +console.log(value); +// returns 'Process 134' +//REMOVE_START +assert.equal(value, 'Process 134'); +await client.del('bike:1'); +//REMOVE_END + +// HIDE_START +await client.close(); +// HIDE_END diff --git a/packages/client/lib/client/socket.ts b/packages/client/lib/client/socket.ts index 58ccbe0b0c5..d7d4984ce77 100644 --- a/packages/client/lib/client/socket.ts +++ b/packages/client/lib/client/socket.ts @@ -238,7 +238,7 @@ export default class RedisSocket extends EventEmitter { } } while (this.#isOpen && !this.#isReady); } - + async #createSocket(): Promise { const socket = this.#socketFactory.create(); @@ -293,7 +293,7 @@ export default class RedisSocket extends EventEmitter { write(iterable: Iterable>) { if (!this.#socket) return; - + this.#socket.cork(); for (const args of iterable) { for (const toWrite of args) { @@ -364,7 +364,7 @@ export default class RedisSocket extends EventEmitter { const jitter = Math.floor(Math.random() * 200); // Delay is an exponential back off, (times^2) * 50 ms, with a maximum value of 2000 ms: const delay = Math.min(Math.pow(2, retries) * 50, 2000); - + return delay + jitter; } } diff --git a/packages/client/lib/commands/SCAN.ts b/packages/client/lib/commands/SCAN.ts index 41991a24172..173e8959afa 100644 --- a/packages/client/lib/commands/SCAN.ts +++ b/packages/client/lib/commands/SCAN.ts @@ -3,7 +3,7 @@ import { RedisArgument, CommandArguments, BlobStringReply, ArrayReply, Command } /** * Common options for SCAN-type commands - * + * * @property MATCH - Pattern to filter returned keys * @property COUNT - Hint for how many elements to return per iteration */ @@ -14,7 +14,7 @@ export interface ScanCommonOptions { /** * Parses scan arguments for SCAN-type commands - * + * * @param parser - The command parser * @param cursor - The cursor position for iteration * @param options - Scan options @@ -36,7 +36,7 @@ export function parseScanArguments( /** * Pushes scan arguments to the command arguments array - * + * * @param args - The command arguments array * @param cursor - The cursor position for iteration * @param options - Scan options @@ -62,7 +62,7 @@ export function pushScanArguments( /** * Options for the SCAN command - * + * * @property TYPE - Filter by value type */ export interface ScanOptions extends ScanCommonOptions { @@ -74,7 +74,7 @@ export default { IS_READ_ONLY: true, /** * Constructs the SCAN command - * + * * @param parser - The command parser * @param cursor - The cursor position to start scanning from * @param options - Scan options @@ -87,14 +87,16 @@ export default { if (options?.TYPE) { parser.push('TYPE', options.TYPE); } + console.log('eeeeeeeeee', parser.redisArgs) }, /** * Transforms the SCAN reply into a structured object - * + * * @param reply - The raw reply containing cursor and keys * @returns Object with cursor and keys properties */ transformReply([cursor, keys]: [BlobStringReply, ArrayReply]) { + console.log(cursor, keys) return { cursor, keys