Commit 9b3038da by Tim Ludwinski

Fixed Issues #118 and #119 and added support for excludeSubkeys

parent ec8a9b77
......@@ -153,6 +153,29 @@ Sometimes you want to see the keys and types come in as it happens. Maybe you h
$ mongo test --eval "var collection = 'users', sort = { updated_at : -1 }, logKeysContinuously = true" variety.js
#### 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.insert({name:"Walter", someNestedObject:{a:{b:{c:{d:{e:1}}}}}, otherNestedObject:{a:{b:{c:{d:{e:1}}}}}});
$ mongo test --eval "var collection = 'users', sort = { updated_at : -1 }, excludeSubkeys = [ 'someNestedObject.a.b' ]" 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 |
| 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 |
+-----------------------------------------------------------------+
#### 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, we have to tell MongoDB it's okay to perform secondary reads
by setting the ```slaveOk``` property to ```true```:
......
......@@ -83,6 +83,11 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */
read('resultsUser', null);
read('resultsPass', null);
read('logKeysContinuously', false);
read('excludeSubkeys', []);
//Translate excludeSubkeys to set like object... using an object for compatibility...
config.excludeSubkeys = config.excludeSubkeys.reduce(function (result, item) { result[item+'.'] = true; return result; }, {});
return config;
};
......@@ -167,7 +172,7 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */
//flattens object keys to 1D. i.e. {'key1':1,{'key2':{'key3':2}}} becomes {'key1':1,'key2.key3':2}
//we assume no '.' characters in the keys, which is an OK assumption for MongoDB
var serializeDoc = function(doc, maxDepth) {
var serializeDoc = function(doc, maxDepth, excludeSubkeys) {
var result = {};
//determining if an object is a Hash vs Array vs something else is hard
......@@ -181,19 +186,21 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */
return !specialObject && (isArray || isObject);
}
function serialize(document, parentKey, maxDepth){
for(var key in document){
function serialize(document, parentKey, maxDepth) {
if(Object.prototype.hasOwnProperty.call(excludeSubkeys, parentKey.replace(".XX.", '.')))
return;
for(var key in document) {
//skip over inherited properties such as string, length, etch
if(!document.hasOwnProperty(key)) {
continue;
}
var value = document[key];
//objects are skipped here and recursed into later
//if(typeof value != 'object')
if(Array.isArray(document))
key = "XX"; //translate unnamed object key from {_parent_name_}.{_index_} to {_parent_name_}.XX
result[parentKey+key] = value;
//it's an object, recurse...only if we haven't reached max depth
if(isHash(value) && maxDepth > 1) {
serialize(value, parentKey+key+'.',maxDepth-1);
serialize(value, parentKey+key+'.', maxDepth-1);
}
}
}
......@@ -206,8 +213,6 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */
var result = {};
for (var key in document) {
var value = document[key];
//translate unnamed object key from {_parent_name_}.{_index_} to {_parent_name_}.XX
key = key.replace(/\.\d+/g,'.XX');
if(typeof result[key] === 'undefined') {
result[key] = {};
}
......@@ -271,7 +276,7 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */
// Merge the keys and types of current object into accumulator object
var reduceDocuments = function(accumulator, object) {
var docResult = analyseDocument(serializeDoc(object, config.maxDepth));
var docResult = analyseDocument(serializeDoc(object, config.maxDepth, config.excludeSubkeys));
mergeDocument(docResult, accumulator);
return accumulator;
};
......@@ -347,7 +352,7 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */
types = typeKeys;
}
return [row._id.key, types, row.totalOccurrences, row.percentContaining.toFixed(maxDigits)];
return [row._id.key, types, row.totalOccurrences, row.percentContaining.toFixed(Math.min(maxDigits, 20))];
});
var table = [headers, headers.map(function(){return '';})].concat(rows);
var colMaxWidth = function(arr, index) {return Math.max.apply(null, arr.map(function(row){return row[index].toString().length;}));};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment