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 ...@@ -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 $ 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 #### #### 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 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```: by setting the ```slaveOk``` property to ```true```:
......
...@@ -83,6 +83,11 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */ ...@@ -83,6 +83,11 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */
read('resultsUser', null); read('resultsUser', null);
read('resultsPass', null); read('resultsPass', null);
read('logKeysContinuously', false); 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; return config;
}; };
...@@ -167,7 +172,7 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */ ...@@ -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} //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 //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 = {}; var result = {};
//determining if an object is a Hash vs Array vs something else is hard //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. */ ...@@ -181,19 +186,21 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */
return !specialObject && (isArray || isObject); return !specialObject && (isArray || isObject);
} }
function serialize(document, parentKey, maxDepth){ function serialize(document, parentKey, maxDepth) {
for(var key in document){ if(Object.prototype.hasOwnProperty.call(excludeSubkeys, parentKey.replace(".XX.", '.')))
return;
for(var key in document) {
//skip over inherited properties such as string, length, etch //skip over inherited properties such as string, length, etch
if(!document.hasOwnProperty(key)) { if(!document.hasOwnProperty(key)) {
continue; continue;
} }
var value = document[key]; var value = document[key];
//objects are skipped here and recursed into later if(Array.isArray(document))
//if(typeof value != 'object') key = "XX"; //translate unnamed object key from {_parent_name_}.{_index_} to {_parent_name_}.XX
result[parentKey+key] = value; result[parentKey+key] = value;
//it's an object, recurse...only if we haven't reached max depth //it's an object, recurse...only if we haven't reached max depth
if(isHash(value) && maxDepth > 1) { 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. */ ...@@ -206,8 +213,6 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */
var result = {}; var result = {};
for (var key in document) { for (var key in document) {
var value = document[key]; 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') { if(typeof result[key] === 'undefined') {
result[key] = {}; result[key] = {};
} }
...@@ -271,7 +276,7 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */ ...@@ -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 // Merge the keys and types of current object into accumulator object
var reduceDocuments = function(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); mergeDocument(docResult, accumulator);
return accumulator; return accumulator;
}; };
...@@ -347,7 +352,7 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */ ...@@ -347,7 +352,7 @@ Released by Maypop Inc, © 2012-2016, under the MIT License. */
types = typeKeys; 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 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;}));}; 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