@keyv/mongo
Table of Contents
MongoDB storage adapter for Keyv
MongoDB storage adapter for Keyv.
Uses TTL indexes to automatically remove expired documents. However MongoDB doesn't guarantee data will be deleted immediately upon expiration, so expiry dates are revalidated in Keyv.
Table of Contents
- Install
- Usage
- Constructor Options
- Properties
- Methods
- Migration from v3 to v6
- License
Install
npm install --save keyv @keyv/mongo
Usage
import Keyv from 'keyv';
import KeyvMongo from '@keyv/mongo';
const keyv = new Keyv(new KeyvMongo('mongodb://user:pass@localhost:27017/dbname'));
keyv.on('error', handleConnectionError);
You can specify the collection name, by default 'keyv' is used.
e.g:
const keyv = new Keyv('mongodb://user:pass@localhost:27017/dbname', { collection: 'cache' });
You can also use the createKeyv helper function to create a Keyv instance with KeyvMongo as the store:
import { createKeyv } from '@keyv/mongo';
const keyv = createKeyv('mongodb://user:pass@localhost:27017/dbname');
Constructor Options
The KeyvMongo constructor accepts a connection URI string or an options object:
// With URI string
const store = new KeyvMongo('mongodb://user:pass@localhost:27017/dbname');
// With options object
const store = new KeyvMongo({
url: 'mongodb://user:pass@localhost:27017/dbname',
collection: 'cache',
db: 'mydb',
useGridFS: false,
});
// With URI string and additional options
const store = new KeyvMongo('mongodb://user:pass@localhost:27017/dbname', { collection: 'cache' });
| Option | Type | Default | Description |
|---|---|---|---|
url |
string |
'mongodb://127.0.0.1:27017' |
MongoDB connection URI |
collection |
string |
'keyv' |
Collection name for storage |
namespace |
string | undefined |
undefined |
Namespace prefix for keys |
useGridFS |
boolean |
false |
Whether to use GridFS for storing values |
db |
string | undefined |
undefined |
Database name |
readPreference |
ReadPreference | undefined |
undefined |
MongoDB read preference for GridFS operations |
Any additional options are passed through to the MongoDB driver as MongoClientOptions.
Properties
Most configuration options are exposed as properties with getters and setters on the KeyvMongo instance. You can read or update them after construction. Some properties like useGridFS are read-only and can only be set via the constructor.
url
Get or set the MongoDB connection URI.
- Type:
string - Default:
'mongodb://127.0.0.1:27017'
const store = new KeyvMongo({ url: 'mongodb://user:pass@localhost:27017/dbname' });
console.log(store.url); // 'mongodb://user:pass@localhost:27017/dbname'
collection
Get or set the collection name used for storage.
- Type:
string - Default:
'keyv'
const store = new KeyvMongo({ url: 'mongodb://user:pass@localhost:27017/dbname' });
console.log(store.collection); // 'keyv'
store.collection = 'cache';
namespace
Get or set the namespace for the adapter. Used for key prefixing and scoping operations like clear().
- Type:
string | undefined - Default:
undefined
const store = new KeyvMongo({ url: 'mongodb://user:pass@localhost:27017/dbname' });
store.namespace = 'my-namespace';
console.log(store.namespace); // 'my-namespace'
useGridFS
Get whether GridFS is used for storing values. When enabled, values are stored using MongoDB's GridFS specification, which is useful for storing large files. This property is read-only and can only be set via the constructor, because the connection shape differs between GridFS and standard modes.
- Type:
boolean - Default:
false - Read-only (set via constructor only)
const store = new KeyvMongo({ url: 'mongodb://user:pass@localhost:27017/dbname', useGridFS: true });
console.log(store.useGridFS); // true
db
Get or set the database name for the MongoDB connection.
- Type:
string | undefined - Default:
undefined
const store = new KeyvMongo({ url: 'mongodb://user:pass@localhost:27017', db: 'mydb' });
console.log(store.db); // 'mydb'
readPreference
Get or set the MongoDB read preference for GridFS operations.
- Type:
ReadPreference | undefined - Default:
undefined
import { ReadPreference } from 'mongodb';
const store = new KeyvMongo({
url: 'mongodb://user:pass@localhost:27017/dbname',
useGridFS: true,
readPreference: ReadPreference.SECONDARY,
});
console.log(store.readPreference); // ReadPreference.SECONDARY
Methods
set
set(key, value, ttl?) - Set a value in the store.
key(string) - The key to set.value(any) - The value to store.ttl(number, optional) - Time to live in milliseconds. If specified, the key will expire after this duration.- Returns:
Promise
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store });
await keyv.set('foo', 'bar');
await keyv.set('foo', 'bar', 5000); // expires in 5 seconds
setMany
setMany(entries) - Set multiple values in the store at once.
entries(Array<{ key: string, value: any, ttl?: number }>) - Array of entries to set. Each entry has akey,value, and optionalttlin milliseconds.- Returns:
Promise
In standard mode, uses a single MongoDB bulkWrite operation for efficiency. In GridFS mode, each entry is set individually in parallel.
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store });
await keyv.set([
{ key: 'key1', value: 'value1' },
{ key: 'key2', value: 'value2', ttl: 5000 },
]);
get
get(key) - Get a value from the store.
key(string) - The key to retrieve.- Returns:
Promise- The stored value, orundefinedif the key does not exist.
In GridFS mode, get also updates the lastAccessed timestamp on the file, which is used by clearUnusedFor.
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store });
await keyv.set('foo', 'bar');
const value = await keyv.get('foo');
console.log(value); // 'bar'
const missing = await keyv.get('nonexistent');
console.log(missing); // undefined
getMany
getMany(keys) - Get multiple values from the store at once.
keys(string[]) - Array of keys to retrieve.- Returns:
Promise- Array of values in the same order as the input keys. Missing keys return> undefinedat their position.
In standard mode, uses a single MongoDB query with the $in operator for efficiency. In GridFS mode, each key is fetched individually.
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store });
await keyv.set('key1', 'value1');
await keyv.set('key2', 'value2');
const values = await keyv.get(['key1', 'key2', 'key3']);
console.log(values); // ['value1', 'value2', undefined]
has
has(key) - Check if a key exists in the store.
key(string) - The key to check.- Returns:
Promise-trueif the key exists,falseotherwise.
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store });
await keyv.set('foo', 'bar');
console.log(await keyv.has('foo')); // true
console.log(await keyv.has('nonexistent')); // false
hasMany
hasMany(keys) - Check if multiple keys exist in the store at once.
keys(string[]) - Array of keys to check.- Returns:
Promise- Array of booleans in the same order as the input keys.
Uses a single MongoDB query with the $in operator for efficiency in both standard and GridFS modes.
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store });
await keyv.set('key1', 'value1');
await keyv.set('key2', 'value2');
const results = await keyv.has(['key1', 'key2', 'key3']);
console.log(results); // [true, true, false]
delete
delete(key) - Delete a key from the store.
key(string) - The key to delete.- Returns:
Promise-trueif the key was deleted,falseif the key was not found.
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store });
await keyv.set('foo', 'bar');
console.log(await keyv.delete('foo')); // true
console.log(await keyv.delete('nonexistent')); // false
deleteMany
deleteMany(keys) - Delete multiple keys from the store at once.
keys(string[]) - Array of keys to delete.- Returns:
Promise-trueif any keys were deleted,falseif none were found.
In standard mode, uses a single MongoDB query with the $in operator. In GridFS mode, all matching files are found and deleted in parallel.
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store });
await keyv.set('key1', 'value1');
await keyv.set('key2', 'value2');
console.log(await keyv.delete(['key1', 'key2', 'key3'])); // true
clear
clear() - Delete all keys in the current namespace.
- Returns:
Promise
Only keys matching the current namespace are removed. If no namespace is set, all keys with an empty namespace are cleared.
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store, namespace: 'my-namespace' });
await keyv.set('key1', 'value1');
await keyv.set('key2', 'value2');
await keyv.clear(); // removes all keys in 'my-namespace'
iterator
iterator(namespace?) - Iterate over all key-value pairs in the store.
namespace(string, optional) - The namespace to iterate over. When used through Keyv, the namespace is passed automatically from the Keyv instance.- Returns:
AsyncGenerator<[string, any]>- An async generator yielding[key, value]pairs.
When used through Keyv, the namespace prefix is stripped from keys automatically.
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store, namespace: 'ns' });
await keyv.set('key1', 'value1');
await keyv.set('key2', 'value2');
for await (const [key, value] of keyv.iterator()) {
console.log(key, value); // 'key1' 'value1', 'key2' 'value2'
}
disconnect
disconnect() - Close the MongoDB connection.
- Returns:
Promise
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store });
// ... use the store ...
await keyv.disconnect();
clearExpired
clearExpired() - Remove all expired files from GridFS. This method only works in GridFS mode and is a no-op that returns false in standard mode.
- Returns:
Promise-trueif running in GridFS mode,falseotherwise.
This is useful for manual cleanup of expired GridFS files, since GridFS does not support MongoDB TTL indexes.
const store = new KeyvMongo({ url: 'mongodb://localhost:27017', useGridFS: true });
await store.set('temp', 'data', 1000); // expires in 1 second
// After expiration...
await store.clearExpired(); // removes expired GridFS files
clearUnusedFor
clearUnusedFor(seconds) - Remove all GridFS files that have not been accessed for the specified duration. This method only works in GridFS mode and is a no-op that returns false in standard mode.
seconds(number) - The number of seconds of inactivity after which files should be removed.- Returns:
Promise-trueif running in GridFS mode,falseotherwise.
The lastAccessed timestamp is updated each time a file is read via get.
const store = new KeyvMongo({ url: 'mongodb://localhost:27017', useGridFS: true });
await store.set('foo', 'bar');
// Remove files not accessed in the last hour
await store.clearUnusedFor(3600);
Migration from v3 to v6
@keyv/mongo is jumping from v3 to v6 because the entire Keyv monorepo is now unified under a single version number. This approach, similar to what other popular open source projects do, keeps all @keyv/* packages in sync and makes it easier to reason about compatibility across the ecosystem.
Breaking Changes
MongoDB Driver Upgraded to v7
The mongodb dependency has been upgraded from ^6.x to ^7.0.0. Review the MongoDB Node.js Driver v7 release notes for any breaking changes that may affect your application.
Event Handling: EventEmitter Replaced with Hookified
KeyvMongo no longer extends Node.js EventEmitter. It now extends Hookified, which provides hook-based event management.
// v3 - EventEmitter
const store = new KeyvMongo('mongodb://localhost:27017');
store.on('error', err => console.error(err));
// v6 - Hookified (same usage for basic events)
const store = new KeyvMongo('mongodb://localhost:27017');
store.on('error', err => console.error(err));
For most use cases the .on() API is the same, but if you relied on EventEmitter-specific methods like .listenerCount(), .rawListeners(), or .prependListener(), check the Hookified documentation for equivalents.
useGridFS is Now Read-Only
The useGridFS property can no longer be changed after construction. The connection shape differs between GridFS and standard modes, so this must be set at construction time.
// v3 - Could change after instantiation
const store = new KeyvMongo('mongodb://localhost:27017');
store.useGridFS = true; // worked in v3
// v6 - Must set at construction
const store = new KeyvMongo({ url: 'mongodb://localhost:27017', useGridFS: true });
console.log(store.useGridFS); // true (read-only)
Property Access Changed from opts to Direct Getters/Setters
Properties are no longer accessed through an opts object. Use the direct getters and setters on the instance instead.
// v3
store.opts.url;
store.opts.collection = 'cache';
// v6
store.url;
store.collection = 'cache';
ttlSupport Property Removed
The ttlSupport property has been removed. If your code checks for TTL support on the adapter, remove those checks.
Namespace Index Change
The unique index on the underlying MongoDB collection has changed from { key: 1 } to { key: 1, namespace: 1 }. This allows the same key name to exist in different namespaces without conflicts. The old index is automatically dropped and replaced on first connection, so no manual migration is needed.
Options Type is Now Strongly Typed
The constructor options no longer accept arbitrary keys via [key: string]: unknown. Options are now strictly typed with explicit properties. Any additional MongoDB driver options should be valid MongoClientOptions properties.
// v3 - Accepted any properties
const store = new KeyvMongo({ url: 'mongodb://...', customProp: true }); // no type error
// v6 - Strictly typed
const store = new KeyvMongo({ url: 'mongodb://...', collection: 'cache' }); // only known props + MongoClientOptions
New Features
createKeyv Helper Function
A new createKeyv helper simplifies creating a Keyv instance with the MongoDB adapter.
import { createKeyv } from '@keyv/mongo';
// Before
const store = new KeyvMongo('mongodb://localhost:27017');
const keyv = new Keyv({ store, namespace: 'my-ns' });
// After
const keyv = createKeyv({ url: 'mongodb://localhost:27017', namespace: 'my-ns' });
setMany Method
Batch set multiple key-value pairs in a single operation using MongoDB bulkWrite.
await store.setMany([
{ key: 'key1', value: 'value1' },
{ key: 'key2', value: 'value2', ttl: 5000 },
]);
hasMany Method
Check if multiple keys exist in a single query using the $in operator.
const results = await store.hasMany(['key1', 'key2', 'key3']);
// [true, true, false]
clearExpired Method
Manually remove expired files from GridFS storage.
const store = new KeyvMongo({ url: 'mongodb://localhost:27017', useGridFS: true });
await store.clearExpired();
clearUnusedFor Method
Remove GridFS files that have not been accessed for a specified duration.
const store = new KeyvMongo({ url: 'mongodb://localhost:27017', useGridFS: true });
await store.clearUnusedFor(3600); // remove files unused for 1 hour