From b68836c59f35923c5a88419ab0bf899088ac5828 Mon Sep 17 00:00:00 2001 From: Simon Prickett Date: Wed, 19 Jan 2022 18:32:20 +0000 Subject: [PATCH] Adds Cuckoo Filter example. (#1843) Co-authored-by: Leibale Eidelman --- examples/README.md | 31 +++++++-------- examples/cuckoo-filter.js | 81 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 15 deletions(-) create mode 100644 examples/cuckoo-filter.js diff --git a/examples/README.md b/examples/README.md index 9a3e14360d..a387b17cb6 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,21 +2,22 @@ This folder contains example scripts showing how to use Node Redis in different scenarios. -| File Name | Description | -|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------| -| `blocking-list-pop.js` | Block until an element is pushed to a list | -| `bloom-filter.js` | Space efficient set membership checks with a [Bloom Filter](https://en.wikipedia.org/wiki/Bloom_filter) using [RedisBloom](https://redisbloom.io) | -| `command-with-modifiers.js` | Define a script that allows to run a command with several modifiers | -| `connect-as-acl-user.js` | Connect to Redis 6 using an ACL user | -| `count-min-sketch.js` | Estimate the frequency of a given event using the [RedisBloom](https://redisbloom.io) Count-Min Sketch | -| `lua-multi-incr.js` | Define a custom lua script that allows you to perform INCRBY on multiple keys | -| `managing-json.js` | Store, retrieve and manipulate JSON data atomically with [RedisJSON](https://redisjson.io/) | -| `search-hashes.js` | Uses [RediSearch](https://redisearch.io) to index and search data in hashes | -| `search-json.js` | Uses [RediSearch](https://redisearch.io/) and [RedisJSON](https://redisjson.io/) to index and search JSON data | -| `set-scan.js` | An example script that shows how to use the SSCAN iterator functionality | -| `stream-producer.js` | Adds entries to a [Redis Stream](https://redis.io/topics/streams-intro) using the `XADD` command | -| `stream-consumer.js` | Reads entries from a [Redis Stream](https://redis.io/topics/streams-intro) using the blocking `XREAD` command | -| `topk.js` | Use the [RedisBloom](https://redisbloom.io) TopK to track the most frequently seen items. | +| File Name | Description | +|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| +| `blocking-list-pop.js` | Block until an element is pushed to a list | +| `bloom-filter.js` | Space efficient set membership checks with a [Bloom Filter](https://en.wikipedia.org/wiki/Bloom_filter) using [RedisBloom](https://redisbloom.io) | +| `command-with-modifiers.js` | Define a script that allows to run a command with several modifiers | +| `connect-as-acl-user.js` | Connect to Redis 6 using an ACL user | +| `count-min-sketch.js` | Estimate the frequency of a given event using the [RedisBloom](https://redisbloom.io) Count-Min Sketch | +| `cuckoo-filter.js` | Space efficient set membership checks with a [Cuckoo Filter](https://en.wikipedia.org/wiki/Cuckoo_filter) using [RedisBloom](https://redisbloom.io) | +| `lua-multi-incr.js` | Define a custom lua script that allows you to perform INCRBY on multiple keys | +| `managing-json.js` | Store, retrieve and manipulate JSON data atomically with [RedisJSON](https://redisjson.io/) | +| `search-hashes.js` | Uses [RediSearch](https://redisearch.io) to index and search data in hashes | +| `search-json.js` | Uses [RediSearch](https://redisearch.io/) and [RedisJSON](https://redisjson.io/) to index and search JSON data | +| `set-scan.js` | An example script that shows how to use the SSCAN iterator functionality | +| `stream-producer.js` | Adds entries to a [Redis Stream](https://redis.io/topics/streams-intro) using the `XADD` command | +| `stream-consumer.js` | Reads entries from a [Redis Stream](https://redis.io/topics/streams-intro) using the blocking `XREAD` command | +| `topk.js` | Use the [RedisBloom](https://redisbloom.io) TopK to track the most frequently seen items. | ## Contributing diff --git a/examples/cuckoo-filter.js b/examples/cuckoo-filter.js new file mode 100644 index 0000000000..e2262a9f02 --- /dev/null +++ b/examples/cuckoo-filter.js @@ -0,0 +1,81 @@ +// This example demonstrates the use of the Cuckoo Filter +// in the RedisBloom module (https://redisbloom.io/) + +import { createClient } from 'redis'; + +async function cuckooFilter() { + const client = createClient(); + + await client.connect(); + + // Delete any pre-existing Cuckoo Filter. + await client.del('mycuckoo'); + + // Reserve a Cuckoo Filter with a capacity of 10000 items. + // https://oss.redis.com/redisbloom/Cuckoo_Commands/#cfreserve + try { + await client.cf.reserve('mycuckoo', 10000); + console.log('Reserved Cuckoo Filter.'); + } catch (e) { + console.log('Error, maybe RedisBloom is not installed?:'); + console.log(e); + } + + // Add items to Cuckoo Filter individually with CF.ADD command. + https://oss.redis.com/redisbloom/Cuckoo_Commands/#cfadd + await Promise.all([ + client.cf.add('mycuckoo', 'leibale'), + client.cf.add('mycuckoo', 'simon'), + client.cf.add('mycuckoo', 'guy'), + client.cf.add('mycuckoo', 'suze'), + client.cf.add('mycuckoo', 'brian'), + client.cf.add('mycuckoo', 'steve'), + client.cf.add('mycuckoo', 'kyle'), + client.cf.add('mycuckoo', 'josefin'), + client.cf.add('mycuckoo', 'alex'), + client.cf.add('mycuckoo', 'nava'), + ]); + + // Add items to the Cuckoo Filter only if they don't exist in it... + // https://oss.redis.com/redisbloom/Cuckoo_Commands/#cfaddnx + const nxReply = await Promise.all([ + client.cf.addNX('mycuckoo', 'kaitlyn'), // New + client.cf.addNX('mycuckoo', 'rachel'), // New + client.cf.addNX('mycuckoo', 'brian') // Previously added + ]); + + console.log('Added members to Cuckoo Filter.'); + console.log('nxReply:'); + + // nxReply looks like this: + // [ + // true, + // true, + // false + // ] + console.log(nxReply); + + // Check whether a member exists with the CF.EXISTS command. + const simonExists = await client.bf.exists('mycuckoo', 'simon'); + console.log(`simon ${simonExists ? 'may' : 'does not'} exist in the Cuckoo Filter.`); + + // Get stats for the Cuckoo Filter with the CF.INFO command: + const info = await client.cf.info('mycuckoo'); + + // info looks like this: + // { + // size: 16440, + // numberOfBuckets: 8192, + // numberOfFilters: 1, + // numberOfInsertedItems: 12, + // numberOfDeletedItems: 0, + // bucketSize: 2, + // expansionRate: 1, + // maxIteration: 20 + // } + console.log(info); + + await client.quit(); +} + +cuckooFilter();