Development > Variety
Schema analyzer: see what fields are in your collection and what's their content
Meet Variety, a Schema Analyzer for MongoDB
This lightweight tool helps you get a sense of your application's schema, as well as any outliers to that schema. Particularly useful when you inherit a codebase with a data dump and want to quickly learn how the data's structured. Also useful for finding rare keys.
“I happen to slowly be falling in love with Variety! It is actually one of the most useful tools to get a sense for a messy/unknown data set, and I have put it in a few of our exercises at Zipfian Academy.”
Jon Dinu Co-founder of Zipfian Academy
“This code saved me at least an hour of work, so least i could do was spend a minute to say thanks. Thank you.”
Also featured on the official MongoDB blog.
Tested Runtimes
| Runtime | Tested Release Lines |
|---|---|
| MongoDB | latest 8.2.x, 8.0.x, 7.0.x, and 5.0.x |
| MongoDB shell | mongosh: MongoDB >= 6.0mongo: MongoDB < 6.0 |
| Node.js | latest 22.x, plus a latest 24.x smoke test |
BSON Type Support Snapshot
The detailed BSON support inventory lives in
docs/bson-type-inventory.md. At a glance,
Variety has intentional, test-backed behavior for every storage-level BSON
value type, though some values are intentionally reported under broader
Variety labels such as Number, Code, String, DBRef, or subtype-specific
BinData-* labels rather than one BSON name per output label.
| Area | Current snapshot |
|---|---|
| Top-level BSON value types | 21 / 21 storage-level BSON value types have intentional, test-backed Variety behavior. Some intentionally merge into broader output labels such as Number, Code, String, DBRef, or per-subtype BinData-* labels. |
| Standard BSON binary subtypes | 10 / 10 standard binary subtypes (0x00 through 0x09) have intentional, test-backed Variety behavior. |
| User-defined binary subtypes | 128 / 128 user-defined subtypes (0x80 through 0xFF) are intentionally mapped as BinData-user[0xNN], with representative test coverage for 0x80, 0x81, and 0xff. |
Vector subtype 9 dtypes |
3 / 3 documented dtypes currently get dtype-specific labels: BinData-vector[INT8], BinData-vector[PACKED_BIT], and BinData-vector[FLOAT32]. Unknown dtype bytes and malformed payloads also have explicit fallback labels. |
An Easy Example
We'll make a collection:
db.users.insertMany([
{name: "Tom", bio: "A nice guy.", pets: ["monkey", "fish"], someWeirdLegacyKey: "I like Ike!"},
{name: "Dick", bio: "I swordfight.", birthday: new Date("1974/03/14")},
{name: "Harry", pets: "egret", birthday: new Date("1984/03/14")},
{name: "Geneviève", bio: "Ça va?"},
{name: "Jim", someBinData: new BinData(2,"1234")},
]);
So, let's see what we've got here:
$ mongosh test --eval "var collection = 'users'" variety.js
+--------------------------------------------------------------------+
| key | types | occurrences | percents |
| ------------------ | -------------------- | ----------- | -------- |
| _id | ObjectId | 5 | 100.0 |
| name | String | 5 | 100.0 |
| bio | String | 3 | 60.0 |
| birthday | Date | 2 | 40.0 |
| pets | String (1),Array (1) | 2 | 40.0 |
| someBinData | BinData-old | 1 | 20.0 |
| someWeirdLegacyKey | String | 1 | 20.0 |
+--------------------------------------------------------------------+
(test is the database containing the collection we are analyzing.)
These examples use mongosh. If your environment still ships the legacy mongo
shell instead, substitute that executable in the commands below.
Hmm. Looks like everybody has a name and _id. Most, but not all have a bio.
Interestingly, it looks like pets can be either an array or a string, but there are more arrays than strings. Will this cause any problems in the application, I wonder?
Seems like the first document created has a weird legacy key—those damn fools who built the prototype didn't clean up after themselves. If there were a thousand such early documents, I might cross-reference the codebase to confirm they are no longer used, and then delete them all. That way they'll not confuse any future developers.
By default, Variety prints results to standard output. If you want to store them in MongoDB for later use, see Save Results in MongoDB For Future Use.
See Progress When Analysis Takes a Long Time
Variety does not print its own progress bar or "percent complete" measurement.
For long-running analyses, watch the MongoDB server logs instead. If MongoDB
reports progress for the underlying work, it will appear in mongod's logs,
not in Variety's output.
Where those logs live depends on how MongoDB is running: they may be in a log
file, available through journalctl, or exposed by your container runtime.
Some MongoDB versions and logging configurations do not emit a percentage for these operations. If you do not see one, Variety may still be running normally; it just means MongoDB is not exposing that measurement in your environment.
Analyze Only Recent Documents
Perhaps you have a really large collection, and you can't wait a whole day for Variety's results.
Perhaps you want to ignore a collection's oldest documents, and only see what the collection's documents' structures have been looking like, as of late.
One can apply a limit constraint, which analyzes only the newest documents in a collection (unless sorting), like so. Note that limit controls which documents are analyzed and therefore affects occurrence counts and percentages — it is not the same as maxExamples, which controls how many sample values appear per key in the output without affecting which documents are scanned.
$ mongosh test --eval "var collection = 'users', limit = 1" variety.js
Let's examine the results closely:
+----------------------------------------------------+
| key | types | occurrences | percents |
| ----------- | ----------- | ----------- | -------- |
| _id | ObjectId | 1 | 100.0 |
| name | String | 1 | 100.0 |
| someBinData | BinData-old | 1 | 100.0 |
+----------------------------------------------------+
We are only examining the newest document here (limit = 1, using Variety's default _id: -1 sort). It belongs to Jim, and only contains the _id, name, and someBinData fields. So it makes sense these are the only three keys.
Analyze Documents to a Maximum Depth
Perhaps you have a potentially very deep nested object structure, and you don't want to see more than a few levels deep in the analysis.
One can apply a maxDepth constraint, which limits the depth Variety will recursively search to find new objects.
db.users.insertOne({name:"Walter", someNestedObject:{a:{b:{c:{d:{e:1}}}}}});
The default will traverse all the way to the bottom of that structure:
$ mongosh test --eval "var collection = 'users'" variety.js
+----------------------------------------------------------------+
| key | types | occurrences | percents |
| -------------------------- | -------- | ----------- | -------- |
| _id | ObjectId | 1 | 100.0 |
| name | String | 1 | 100.0 |
| someNestedObject | Object | 1 | 100.0 |
| someNestedObject.a | Object | 1 | 100.0 |
| someNestedObject.a.b | Object | 1 | 100.0 |
| someNestedObject.a.b.c | Object | 1 | 100.0 |
| someNestedObject.a.b.c.d | Object | 1 | 100.0 |
| someNestedObject.a.b.c.d.e | Number | 1 | 100.0 |
+----------------------------------------------------------------+
$ mongosh test --eval "var collection = 'users', maxDepth = 3" variety.js
+----------------------------------------------------------+
| key | types | occurrences | percents |
| -------------------- | -------- | ----------- | -------- |
| _id | ObjectId | 1 | 100.0 |
| name | String | 1 | 100.0 |
| someNestedObject | Object | 1 | 100.0 |
| someNestedObject.a | Object | 1 | 100.0 |
| someNestedObject.a.b | Object | 1 | 100.0 |
+----------------------------------------------------------+
As you can see, Variety only traversed three levels deep.
Analyze a Subset of Documents
Perhaps you have a large collection, or you only care about some subset of the documents.
One can apply a query constraint, which takes a standard MongoDB query object, to filter the set of documents required before analysis.
$ mongosh test --eval "var collection = 'users', query = {'caredAbout':true}" variety.js
MongoDB shell constructors such as ObjectId(...) can be used inside that
evaluated query:
$ mongosh myDb --eval "var collection = 'myCollection', query = {company: ObjectId('5a6b446d46246c5b6eaaa4a4')}" variety.js
The first-party variety DB/COLLECTION CLI keeps --query limited to strict
JSON, so use --eval when a filter needs shell-side values:
$ variety myDb/myCollection --quiet --outputFormat json --eval "var query = {company: ObjectId('5a6b446d46246c5b6eaaa4a4')}"
Extended JSON support for --query is being discussed in issue #267. Hat tip: @mariusbancos (#146).
Analyze Documents Sorted In a Particular Order
Perhaps you want to analyze a subset of documents sorted in an order other than creation order, say, for example, sorted by when documents were updated.
One can apply a sort constraint, which analyzes documents in the specified order like so:
$ mongosh test --eval "var collection = 'users', sort = { updated_at : -1 }" variety.js
Include Last Value
One can also apply a lastValue constraint to capture one representative value for each key.
$ mongosh test --eval "var collection = 'orders', lastValue = true" variety.js
Via the first-party CLI:
$ variety test/orders --last-value
+--------------------------------------------------------------------------------------------+
| key | types | occurrences | percents | lastValue |
| --------------- | ------------ | ----------- | -------- | -------------------------------- |
| _id | ObjectId | 1 | 100.0 | 5a834b76f4d3fa6e578a67f6 |
| age | Number | 1 | 100.0 | 38.2569 |
| animals | Array | 1 | 100.0 | [Array] |
| animals.XX.type | String | 1 | 100.0 | dog |
| balance | NumberLong | 1 | 100.0 | 1236458945684846 |
| date | Date | 1 | 100.0 | 2017-12-17T19:46:09.000Z |
| fn | Object | 1 | 100.0 | [Object] |
| fn.code | String | 1 | 100.0 | function (x, y){ return x + y; } |
| name | String | 1 | 100.0 | John |
| nil | null | 1 | 100.0 | [null] |
| uid | BinData-UUID | 1 | 100.0 | 3b241101e2bb42558caf4136c566a962 |
+--------------------------------------------------------------------------------------------+
Variety captures each lastValue from the first matching document it sees in the configured sort order. If you do not provide sort, it uses the default { _id: -1 } ordering, so these values come from the newest matching documents encountered during the scan.
Date is converted into an ISO 8601 string, ObjectId into string, and binary data into hex. Other types are shown in square brackets.
Variety reports BSON wrapper types such as Decimal128, Timestamp, Code, BSONRegExp, MinKey, MaxKey, and DBRef by their BSON type names in the types column. BSON Double and Int32 are the current exception: the shell-backed analysis path receives both as plain JavaScript numbers, so Variety reports both as Number.
Collect Multiple Example Values
When a single representative value is not enough, use maxExamples to gather up to N sample values per key. Unlike lastValue, which captures only one value from the first matching document, maxExamples accumulates examples across all analyzed documents (up to the specified count). Unlike limit, it does not change which documents are analyzed — all documents still contribute to the schema; maxExamples only controls how many sample values are retained per key in the output.
$ mongosh test --eval "var collection = 'users', maxExamples = 3" variety.js
+---------------------------------------------------------------------------------------------------------------------------------------------------+
| key | types | occurrences | percents | examples |
| ------------------ | -------------------- | ----------- | -------- | ---------------------------------------------------------------------------- |
| _id | ObjectId | 5 | 100.0 | 69e6cbc2e9ccbf038c44ba8d, 69e6cbc2e9ccbf038c44ba8c, 69e6cbc2e9ccbf038c44ba8b |
| name | String | 5 | 100.0 | Jim, Geneviève, Harry |
| bio | String | 3 | 60.0 | Ça va?, I swordfight., A nice guy. |
| birthday | Date | 2 | 40.0 | 1984-03-14T00:00:00.000Z, 1974-03-14T00:00:00.000Z |
| pets | String (1),Array (1) | 2 | 40.0 | egret, [Array] |
| someBinData | BinData-old | 1 | 20.0 | d76df8 |
| someWeirdLegacyKey | String | 1 | 20.0 | I like Ike! |
+---------------------------------------------------------------------------------------------------------------------------------------------------+
(ObjectId hex strings are runtime-generated; exact values will differ.)
Via the first-party CLI:
$ variety test/users --maxExamples 3
The same serialisation rules as lastValue apply: Date → ISO 8601 string, ObjectId → hex string, binary data → hex. Non-serialisable types such as Array or Object appear as [TypeName] placeholders.
maxExamples and lastValue are independent; both can be used together.
Thanks to @humanitiesclinic for suggesting this feature (#154).
Output Formats and Plugins
Variety ships two built-in output formats. For custom output, plugins can supply their own formatter.
Built-in Formats
Two formatters are included out of the box:
| Format | Description |
|---|---|
ascii (default) |
Padded table, as shown throughout this README |
json |
Pretty-printed JSON array, suitable for piping to other tools |
Select a format with the outputFormat option:
$ mongosh test --quiet --eval "var collection = 'users', outputFormat='json'" variety.js
Passing an unrecognised value throws an error listing the valid options.
Hide Frequency Columns in ASCII Output
If you only care about schema shape and type coverage, set hideFrequencyColumns
to true to remove the occurrences and percents columns from the built-in
ASCII table:
$ mongosh test --eval "var collection = 'users', hideFrequencyColumns = true" variety.js
Via the first-party CLI:
$ variety test/users --hide-frequency-columns
+-------------------------------------------+
| key | types |
| ------------------ | -------------------- |
| _id | ObjectId |
| name | String |
| bio | String |
| birthday | Date |
| pets | String (1),Array (1) |
| someBinData | BinData-old |
| someWeirdLegacyKey | String |
+-------------------------------------------+
This option affects only built-in ASCII output. JSON output and persisted
results still include totalOccurrences and percentContaining.
Plugins
A plugin is a .js file that exports a plain object with lifecycle hooks. Load one with the plugins option (comma-separated for multiple):
$ mongosh test --quiet --eval "var collection='users', plugins='/path/to/my-plugin.js'" variety.js
Via the first-party CLI (use --plugin once per plugin):
$ variety test/users --quiet --plugin /path/to/my-plugin.js
Pass per-plugin configuration by appending |key=value after the path:
$ mongosh test --quiet --eval "var collection='users', plugins='/path/to/my-plugin.js|delimiter=;'" variety.js
Via the first-party CLI (use ?key=value instead of |, and & between multiple params):
$ variety test/users --quiet --plugin '/path/to/my-plugin.js?delimiter=;'
For multiple plugins, repeat the flag:
$ variety test/users --quiet --plugin /path/to/formatter.js --plugin '/path/to/other.js?key=val'
See CONTRIBUTING.md for the full hook reference and a guide to writing and testing plugins.
Quiet Option
Both MongoDB and Variety output some additional information to standard output. If you want to remove this info, you can use the --quiet option provided by the MongoDB shell executable.
Variety can also read that option and mute unnecessary output. This is useful in connection with outputFormat=json. You would then receive only JSON, without any other characters around it.
$ mongosh test --quiet --eval "var collection = 'users', outputFormat='json', sort = { updated_at : -1 }" variety.js
Log Keys and Types As They Arrive Option
Sometimes you want to see the keys and types come in as it happens. Maybe you have a large dataset and want accurate results, but you also are impatient and want to see something now. Or maybe you have a large mangled dataset with crazy keys (that probably shouldn't be keys) and Variety is going out of memory. This option will show you the keys and types as they come in and help you identify problems with your dataset without needing the Variety script to finish.
$ mongosh test --eval "var collection = 'users', sort = { updated_at : -1 }, logKeysContinuously = true" variety.js
Via the first-party CLI:
$ variety test/users --sort '{"updated_at":-1}' --log-keys-continuously
Exclude Subkeys
Sometimes you inherit a database full of junk. Maybe the previous developer put data in the database keys, which causes Variety to go out of memory when run. After you've run the logKeysContinuously to figure out which subkeys may be a problem, you can use this option to run Variety without those subkeys.
db.users.insertOne({name:"Walter", someNestedObject:{a:{b:{c:{d:{e:1}}}}}, otherNestedObject:{a:{b:{c:{d:{e:1}}}}}});
$ mongosh test --eval "var collection = 'users', sort = { updated_at : -1 }, excludeSubkeys = [ 'someNestedObject.a.b' ]" variety.js
Via the first-party CLI (repeat --exclude-subkeys for multiple paths):
$ variety test/users --sort '{"updated_at":-1}' --exclude-subkeys someNestedObject.a.b
+-----------------------------------------------------------------+
| key | types | occurrences | percents |
| --------------------------- | -------- | ----------- | -------- |
| _id | ObjectId | 1 | 100.0 |
| name | String | 1 | 100.0 |
| someNestedObject | Object | 1 | 100.0 |
| someNestedObject.a | Object | 1 | 100.0 |
| someNestedObject.a.b | Object | 1 | 100.0 |
| otherNestedObject | Object | 1 | 100.0 |
| otherNestedObject.a | Object | 1 | 100.0 |
| otherNestedObject.a.b | Object | 1 | 100.0 |
| otherNestedObject.a.b.c | Object | 1 | 100.0 |
| otherNestedObject.a.b.c.d | Object | 1 | 100.0 |
| otherNestedObject.a.b.c.d.e | Number | 1 | 100.0 |
+-----------------------------------------------------------------+
Show Array Elements
By default, Variety suppresses keys that end with an array index (e.g. tags.XX), because the parent key already captures the Array type. If you want to see the types of the values inside primitive arrays — useful for verifying element-type consistency — set showArrayElements to true:
$ mongosh test --eval "var collection = 'users', showArrayElements = true" variety.js
Via the first-party CLI:
$ variety test/users --show-array-elements
For example, given documents like:
db.users.insertMany([
{ name: 'Alice', tags: ['a', 'b'] },
{ name: 'Bob', tags: ['c', 1] }
]);
Without showArrayElements, only the tags key (type Array) appears. With it enabled, you also see:
+----------------------------------------------------------+
| key | types | occurrences | percents |
| ------- | --------------------- | ----------- | -------- |
| tags | Array | 2 | 100.0 |
| tags.XX | String (2),Number (1) | 2 | 100.0 |
+----------------------------------------------------------+
This reveals that tags contains mixed element types across the collection.
Compact Array Types
If you want the parent array key itself to carry a more informative summary than plain Array, set compactArrayTypes to true:
$ mongosh test --eval "var collection = 'users', compactArrayTypes = true" variety.js
Via the first-party CLI:
$ variety test/users --compact-array-types
With this option enabled, parent keys can be reported as values such as Array(String), Array(Number|String), or Array(empty) instead of just Array.
This option is complementary to showArrayElements: compactArrayTypes makes the parent key more descriptive, while showArrayElements still exposes the tags.XX-style child keys when you want per-element detail.
Thanks to @oufeng for suggesting this feature (#166).
Secondary Reads
Analyzing a large collection on a busy replica set primary could take a lot longer than if you read from a secondary. To do so, tell MongoDB to use the secondary read preference
by setting the secondaryOk property to true:
$ mongosh secondary.replicaset.member:31337/somedb --eval "var collection = 'users', secondaryOk = true" variety.js
Via the first-party CLI:
$ variety somedb/users --host secondary.replicaset.member --port 31337 --secondary-ok
secondaryOk replaces the old slaveOk name; see issue #309.
Save Results in MongoDB For Future Use
By default, Variety prints results only to standard output and does not store them in MongoDB itself. If you want to persist them automatically in MongoDB for later usage, you can set the persistResults parameter.
Variety then stores result documents in the varietyResults database, and the collection name is derived from the source collection's name.
If the source collection's name is users, Variety stores results in the usersKeys collection under the varietyResults database.
$ mongosh test --quiet --eval "var collection = 'users', persistResults=true" variety.js
Via the first-party CLI:
$ variety test/users --quiet --persist-results
To persist to an alternate MongoDB database, you may specify the following parameters:
resultsDatabase- The database to store Variety results in. Accepts either a database name or ahost[:port]/databaseURL.resultsCollection- Collection to store Variety results in. WARNING: This collection is dropped before results are inserted.resultsUser- MongoDB username for results databaseresultsPass- MongoDB password for results database
$ mongosh test --quiet --eval "var collection = 'users', persistResults=true, resultsDatabase='db.example.com/variety'" variety.js
Via the first-party CLI:
variety test/users --quiet --persist-results --results-database db.example.com/variety --results-collection myKeys --results-user reporter --results-password secret
Reserved Keys
Variety expects keys to be well formed, not having any .s in them (MongoDB 2.4 allows dots in certain cases). Also MongoDB uses the pseudo keys XX and keys corresponding to the regex XX\d+XX.* for use with arrays. You can change the string XX in these patterns to whatever you like if there is a conflict in your database using the arrayEscape parameter.
$ mongosh test --quiet --eval "var collection = 'users', arrayEscape = 'YY'" variety.js
Via the first-party CLI:
$ variety test/users --array-escape YY
Command Line Interface
This NPM package publishes a built-in variety executable that resolves the bundled variety.js, prefers mongosh when available, and falls back to the legacy mongo shell.
The primary interface is:
variety DB/COLLECTION [options]
Examples:
variety test/users
variety test/users --outputFormat json --quiet
variety logs/webserver --limit 100 --maxDepth 3 --sort '{"created":-1}'
variety test/users --query '{"bio":{"$exists":true}}' --host localhost --port 27017
Authenticated Remote Databases
For a remote MongoDB instance that requires authentication, pass the connection details through the built-in CLI:
variety app/users --host db.example.com --port 27017 --username report_reader --password secret --authenticationDatabase admin --quiet
The built-in CLI also supports MongoDB connection strings directly:
variety app/users --uri "mongodb://report_reader:secret@db.example.com:27017/app?authSource=admin" --quiet
--uri accepts both mongodb:// and mongodb+srv:// connection strings while
keeping the existing DB/COLLECTION target syntax:
- If the URI omits a database name, Variety uses the positional
DB. - If the URI includes a database name, it must match the positional
DB. --uricannot be combined with--host,--port,--username,--password, or--authenticationDatabase.
The equivalent direct Mongo shell invocation uses the connection string as the
shell target and sets the collection through --eval:
mongosh "mongodb://report_reader:secret@db.example.com:27017/app?authSource=admin" --quiet --eval "var collection = 'users'" variety.js
Structured flags such as --query and --sort accept strict JSON. Connection
flags such as --host, --port, --username, --password, --authenticationDatabase,
--uri, and --quiet shape the Mongo shell invocation. --eval remains
available as an escape hatch when you need to append raw JavaScript assignments.
If the JavaScript you need to append begins with -- and also matches a Variety CLI flag name, use the inline form --eval=... so the parser does not treat it as another option.
When you invoke variety with no CLI arguments, the documented compatibility environment variables remain supported:
| Variable | Description |
|---|---|
DB |
MongoDB database name to pass to the shell |
EVAL_CMDS |
JavaScript assignments forwarded via --eval (e.g. var collection = 'users', limit = 100) |
VARIETYJS_DIR |
Directory containing variety.js; when omitted, the CLI uses the bundled script |
Examples:
DB=test EVAL_CMDS="var collection = 'users', outputFormat='json'" variety
DB=test EVAL_CMDS="var collection = 'users', maxDepth = 3, limit = 500" variety
Direct mongosh ... variety.js usage remains supported and is still useful when you want the most transparent low-level invocation for debugging or advanced shell work.
Loading Variety From an Interactive Mongo Shell
If you are already inside mongosh or the legacy mongo shell, define the
same globals you would normally pass with --eval, then load variety.js:
var collection = 'users';
load('/path/to/variety.js');
The load() call executes Variety immediately; there is no separate function
to call after the script loads. Set any additional options before load():
var collection = 'users';
var outputFormat = 'json';
var limit = 100;
load('/path/to/variety.js');
This low-level form is useful for exploratory shell sessions or debugging. For
regular terminal use, prefer the packaged variety DB/COLLECTION [options]
command.
Hat tip: @abrin (issue #131). Follow-up: issue #264
Calling Variety From Node.js
Variety can be automated from a Node.js application by spawning the packaged
variety executable, but it is not an in-process Node.js library API. For
machine-readable output, run the CLI with --outputFormat json --quiet and
parse stdout:
const { execFile } = require('node:child_process');
const { promisify } = require('node:util');
const execFileAsync = promisify(execFile);
async function analyzeCollection() {
const { stdout } = await execFileAsync('variety', [
'test/users',
'--outputFormat',
'json',
'--quiet',
]);
return JSON.parse(stdout);
}
Be careful exposing this pattern from a web endpoint. Keep database credentials server-side, validate collection names and options, and pass arguments as an array instead of constructing a shell command from request input. If an endpoint only needs the available field names, the MongoDB Node.js driver may be a better fit than shelling out to Variety for each request.
Hat tip: @ashishtilara (issue #125). Follow-up: issue #263
Note: variety-cli, a formerly available companion project that offered higher-level argument parsing, has been archived and is no longer maintained.
"But my dad told me MongoDB is a schemaless database!"
First of all, your father is a great guy. Moving on…
A MongoDB collection does not enforce a predefined schema like a relational database table. Still, documents in real-world collections nearly always have large sections for which the format of the data is the same. In other words, there is a schema to the majority of collections, it's just enforced by the application, rather than by the database system. And this schema is allowed to be a bit fuzzy, in the same way that a given table column might not be required in all rows, but to a much greater degree of flexibility. So we examine what percent of documents in the collection contain a key, and we get a feel for, among other things, how crucial that key is to the proper functioning of the application.
Dependencies
The packaged variety executable runs on Node.js and a MongoDB shell (mongosh is preferred; the legacy mongo shell still works where available). If you run Variety directly as mongosh ... variety.js, the shell path still depends only on MongoDB plus a MongoDB shell.
Contributing
For setup, repo layout and the variety.js build, testing, linting, and how to report issues or send patches, see CONTRIBUTING.md.
Core Maintainers
- Tomáš Dvořák (LinkedIn)
- Eve Freeman (Github)
- James Cropcho (original creator of Variety) (Twitter/X)
Special Thanks
Additional special thanks to Gaëtan Voyer-Perraul (@gatesvp) and Kristina Chodorow (@kchodorow) for answering other people's questions about how to do this on Stack Overflow, thereby providing me with the initial seed of code which grew into this tool.
Much thanks also, to Kyle Banker (@Hwaet) for writing an unusually good book on MongoDB, which has taught me everything I know about it so far.
Tools Which Use Variety (Open Source)
Know of one? Built one? Let us know!
Stay Safe
I have every reason to believe this tool will not corrupt your data or harm your computer. But if I were you, I would not use it in a production environment.
Released by James Cropcho, © 2012–2026, under the MIT License.