{"_id":"mongo-dynamic-indexer","_rev":"34-a14846c0f705e6156077350730f5921b","name":"mongo-dynamic-indexer","description":"Automatically selects and reccomends indexes based on your queries and data,","dist-tags":{"latest":"1.1.16"},"versions":{"1.0.0":{"name":"mongo-dynamic-indexer","version":"1.0.0","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.0.0","scripts":{},"_shasum":"aee724de35c48b023a0960b69a7d17ec4dd8296b","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"aee724de35c48b023a0960b69a7d17ec4dd8296b","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.0.0.tgz","integrity":"sha512-vCYu2WUOxq53oNwco14ORVTVnwEQBpDPL6jGH0tRpvgBYaskbsEgtESZlFLiQgcjt5bQz2cwv+P/7M3I/G6rSA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCX4VtWdctBOg+8y2NADzYI+rxe1+bCt9qY2NnOWEzK2QIhAP8MaQR3iEI6pouI5oN0iFiw73LK4tCIudTWa3qu9ggT"}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.0.0.tgz_1470930485312_0.6143285890575498"}},"1.0.1":{"name":"mongo-dynamic-indexer","version":"1.0.1","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.0.1","scripts":{},"_shasum":"7f1f5d930dc0ada64cd946747f2ce3c8afb28ba2","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"7f1f5d930dc0ada64cd946747f2ce3c8afb28ba2","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.0.1.tgz","integrity":"sha512-Stu+G2vJby8+ywXNl35rEyruqtgJejHiexcWEeOOQCM6/3V3zI2WxQ6x4oS+4XSbw0syH8cIiv+RefiWTw4uGw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCL6JFrs94NDtDHpTczq9r0Qa1nZvNDK3EFZUZASoJZbQIgB3sky/fHo6DIb5FXIRyH1aBZqcF7+El+4WEbLkrEPBo="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.0.1.tgz_1470935295404_0.6159388534724712"}},"1.0.2":{"name":"mongo-dynamic-indexer","version":"1.0.2","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.0.2","scripts":{},"_shasum":"ed6878afa71c0316f39ffca7aa2c17af3cd10fd7","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"ed6878afa71c0316f39ffca7aa2c17af3cd10fd7","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.0.2.tgz","integrity":"sha512-ZZCv1b6sdqm2HKQoANtaqjQTak/nqx63RQO0WGYcP7w+kW50QHL40Bik0sKZdfn/XopMSPBSEfuxleTFSMVfxQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDd7dogrTE/XX0K3nAy/usFg1fz5noJQutpdnAkXYe1/AIgKEdZMFlwTIllf12CWtA/8QvkfADMyYHXE9ennpw1QOo="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.0.2.tgz_1470937896542_0.08497889386489987"}},"1.0.3":{"name":"mongo-dynamic-indexer","version":"1.0.3","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.0.3","scripts":{},"_shasum":"79b047d30ea9d6e986c61952ade6117c7fa915db","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"79b047d30ea9d6e986c61952ade6117c7fa915db","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.0.3.tgz","integrity":"sha512-63RewexSXemrc0jMAENd+MJMuSb9gwsDi8y7zCPpi6uInnD0LM8CTvelVLDm+SakJaw1CtFsR7+3OgnEJCVVxQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCumts9pEzEoYJo6i8a2SdzlXyNHzuuDb31jTSaNBTvnQIgD4ItUouDE2bXXqrG/IYgFfA97umV+ggrQrnEbntTzr8="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.0.3.tgz_1471016646047_0.8065607263706625"}},"1.0.4":{"name":"mongo-dynamic-indexer","version":"1.0.4","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.0.4","scripts":{},"_shasum":"afc4275ececae5efb9f93d467a0bb6aac9084bfa","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"afc4275ececae5efb9f93d467a0bb6aac9084bfa","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.0.4.tgz","integrity":"sha512-WGP+VyWdS6eDRoQ2RgTgkUKm1G2my3DvsqDi/O2jupfvwpaqQZlM+jkG3qgFUYIZjWqjcPwTersnv7SserwQKw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCyZY7KuJTTwIKWPHA4OP9o8nPwZf8eYccOlY9CxEpHMAIgNcoOFUSRkGejuE3rW2m9UOtOfim2oRlbzBsI38/pxSA="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.0.4.tgz_1471300398626_0.6566124656237662"}},"1.0.5":{"name":"mongo-dynamic-indexer","version":"1.0.5","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.0.5","scripts":{},"_shasum":"b1deb0556074e5160299be4bbe7352e7c8949ef9","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"b1deb0556074e5160299be4bbe7352e7c8949ef9","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.0.5.tgz","integrity":"sha512-jc7zwLxhsJDwNWLQge7Fm7U2zZo9TNIKXoPdAFi7H0DtdTgu3teFLvLoCqdG8o8I/qFyTKo1fbDQ9L/AuYkGgQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC4VxMatslm3vnZlOMLgLaVKEa8mdBrtrN1EdHUyRJQ3gIgIs44KgBzf0iVYCQM9IqqPvBtGp6WtuPICopuPLMwBq4="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.0.5.tgz_1471454383437_0.12551266164518893"}},"1.0.6":{"name":"mongo-dynamic-indexer","version":"1.0.6","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.0.6","scripts":{},"_shasum":"13ded73d50f9388a694743d1707706c617dce5c8","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"13ded73d50f9388a694743d1707706c617dce5c8","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.0.6.tgz","integrity":"sha512-LrZ0yzZcp7YG5mR2Ff976adRIqMbP/OZ7oWwzBrKOlYqAOVDNZsHahwUWJxI/8iydUmoXY9sCk5DVa+vgXmvSQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGEMEZz91orqPq32k3TC2gBnE8oSfXaOQU3yTb24YTBOAiEAnDBrShr4TOfrqu+HWHgbe7Y3gDoUwoE4lVyq2pnI8V0="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.0.6.tgz_1471456237693_0.0017028118018060923"}},"1.0.7":{"name":"mongo-dynamic-indexer","version":"1.0.7","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.0.7","scripts":{},"_shasum":"aece521fd189e92c647871d8f87c19135d473684","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"aece521fd189e92c647871d8f87c19135d473684","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.0.7.tgz","integrity":"sha512-3PDjf62FxTdfltoQWcLt2D5pjoqCfAe9Qyy2YC/jreOBUfMsjBLP2rk+x74KrCMULLI1o+tHiHZKfAUs1SGT1w==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCDFx4Csn7GMx0wgd+iZJS/N14EAYsjBzoFY+g+f+yQZQIgB7MK+M9S2bjuDsmxGxXeHhh/vplSGgr/bggSlp4zDdY="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.0.7.tgz_1471542103038_0.3069138824939728"}},"1.0.8":{"name":"mongo-dynamic-indexer","version":"1.0.8","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.0.8","scripts":{},"_shasum":"549d7e36cd473d6e921d8da7364ba1e2c0cb7536","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"549d7e36cd473d6e921d8da7364ba1e2c0cb7536","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.0.8.tgz","integrity":"sha512-V2pOicAL0O/SHxvNLJ8ucqDkFVPYu9dD9UAad8a7NXh7sQfVJJnuxTYgwxRG5OUJ8VLvtlqMbegbN3I9ss6v3g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFdkNe57qBzrkr8sKvlKOJIPgTR2aWgCA9+GCIGyPrG5AiEAodujZ6L2O2LLlcuX1rYkvyXEu9VqCeUTzlcuhI/PNjQ="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.0.8.tgz_1471554377468_0.7881867941468954"}},"1.0.9":{"name":"mongo-dynamic-indexer","version":"1.0.9","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.0.9","scripts":{},"_shasum":"c35fb1f652a38da0ae3a955bbf90da088a26e7e4","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"c35fb1f652a38da0ae3a955bbf90da088a26e7e4","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.0.9.tgz","integrity":"sha512-eh92hnHAWnXwL9xcv78//uBon+lnBXpBtrl4PVdIOsR7zDikbIkbYzfrS05q9HFpbqPUrJw7Zxe9raq3y4SC8w==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHFsF78COnEu+w5Jb4ixQj2bOpRigqzgVkpXIzJSnel0AiEA9lOMXLsZmOgX+//ikK+yYlD5YyKdmXUlwn371hP7xFs="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.0.9.tgz_1471979978274_0.40909537742845714"}},"1.1.0":{"name":"mongo-dynamic-indexer","version":"1.1.0","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.0","scripts":{},"_shasum":"be5f5f37748bfda7a3f66188d4bc304ca9ccb591","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"be5f5f37748bfda7a3f66188d4bc304ca9ccb591","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.0.tgz","integrity":"sha512-qu+gVIbrNiCGwhIrVTCKWagNNTdK6Wsrk9kxUQJU0jLjps0a9OAm1EL83zwHcl75pEfAUa6+b4ylZBuZvx29HQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC8pZlsYHas5CbMbvB51qwKp7G8vXKVQkOMWbnxPij6mgIhANCdgbqeP0rnKOKi6dR+VZbn4KI87+Edvj+Ohs98/RtD"}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.0.tgz_1472143488567_0.3651357276830822"}},"1.1.1":{"name":"mongo-dynamic-indexer","version":"1.1.1","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.1","scripts":{},"_shasum":"5270d3555d242dc8dde8840627a16469cb10a741","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"5270d3555d242dc8dde8840627a16469cb10a741","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.1.tgz","integrity":"sha512-lsyDmvxLhDZaaoBx27mzOjf0UHJnNAx6OWTtX2TcrvfEtTH+MVvhNUiYD7ZUfAslZM/VGRfEptuk7MJbcJh/DQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICsWkJcTD8VSDzQTqKfzxyQOksmZazAaUu1CAoZ+L3VfAiEA8qSlkBNeqOse0SV2fHF2mh8QgCFPKbf0lQ2HikXSNgg="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.1.tgz_1472150475505_0.11718193185515702"}},"1.1.2":{"name":"mongo-dynamic-indexer","version":"1.1.2","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.2","scripts":{},"_shasum":"95adb1582c648f3a698c1ba276379c92006b85d1","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"95adb1582c648f3a698c1ba276379c92006b85d1","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.2.tgz","integrity":"sha512-ITdtsIttcoC4IEDuiycZInQej1MU9NLHjJ/OCx9JIWXjKwil1XlyqbYPvZPl4+sZ2uCMckWR810n8G29z/ZmoA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC/am54Hql+l9ibxs1hebTKDD7cJmmkgdL8aKQ4m+nkrgIhAIEHVzLplbx5SJBjh9WefP6CDZ9aBC8jctAcVrXo3O5s"}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.2.tgz_1472151481895_0.2001924840733409"}},"1.1.3":{"name":"mongo-dynamic-indexer","version":"1.1.3","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.3","scripts":{},"_shasum":"71de2054cd5c2d6f11a72e763492fa74cbb6c357","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"71de2054cd5c2d6f11a72e763492fa74cbb6c357","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.3.tgz","integrity":"sha512-Fz02KPnBwTHrPFSujlcVA4X1go4XXTnz+nSJlNoyj9gKFdyKWmKPp56Rize466qqOaPrYe4WFmeVh5dCTy2UVw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDxX9U/EevJ+jbExPjfNfd3EZEgsns5YYyu6NffUFmUSAIhALplBMKLVLNcMAoHs1DgXUD8W+Wc16YbbLQ1mCAglYdu"}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.3.tgz_1472152871726_0.3471386940218508"}},"1.1.4":{"name":"mongo-dynamic-indexer","version":"1.1.4","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.4","scripts":{},"_shasum":"25e8a399a1dc29088baf23e06b0b372c00c1cf4e","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"25e8a399a1dc29088baf23e06b0b372c00c1cf4e","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.4.tgz","integrity":"sha512-e12GbggW3aHVGgve0bLMNn0ES3dhTSe+fXJo5uOB/RjxZiSeZ1KuMglwO3AxQW4qv3LPNW1a7aRDHtRuG0+6wQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHfH9VEYaa3nCZfRTFjvHMftvkwZpARDI0xx61473VbAAiEAhed0ljMEy8ckV2J+Cjl6DyEztG7EQoNEE7Tx7Zk7i3U="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.4.tgz_1472232361458_0.7655903827399015"}},"1.1.5":{"name":"mongo-dynamic-indexer","version":"1.1.5","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.5","scripts":{},"_shasum":"6a4a2305d6dc58559b8f14a485517987a62b9b7b","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"6a4a2305d6dc58559b8f14a485517987a62b9b7b","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.5.tgz","integrity":"sha512-D9ewS8zg4/F1DHvvOiB3FyikXtXN0624YbEo/GKY8GmlefazpxmqjRN8GHPXObu+GN3qP9x05akStAcm76gORg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICR1fkjJ63uDG/5eV2Wb7gcFA26BY9SXtEUpk+qRXp87AiBV2rGpQxoHU7YCbp/g6nF/wtMfPFsJI5/Y3EATVwOAfA=="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.5.tgz_1472482435110_0.32510734465904534"}},"1.1.6":{"name":"mongo-dynamic-indexer","version":"1.1.6","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.6","scripts":{},"_shasum":"650d4bc231a4e06d94b215b6e94a1757e6c5df8e","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"650d4bc231a4e06d94b215b6e94a1757e6c5df8e","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.6.tgz","integrity":"sha512-siuCHEiFH3ncWEieG7shyYjVypuhQ48itM1Kr5BI4zZrigeFD85pAWiDZpr8i9g3xwJxKcUYfRTxtAoZXjKpvA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDg/Ae/D6XAFLCXSdoVsm0A8n1RgiMGswU5r8YmcUXbTQIgbmSTC4dlDZ0voFWszIuNSt2n6AR9D4ew+9Ex63nXn0U="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.6.tgz_1472490379944_0.33294750610366464"}},"1.1.7":{"name":"mongo-dynamic-indexer","version":"1.1.7","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.7","scripts":{},"_shasum":"23c1cf6d9249d63660332bfe02c8a4e426770f10","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"23c1cf6d9249d63660332bfe02c8a4e426770f10","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.7.tgz","integrity":"sha512-byxxWwA64KYJRFFc5En3D2NdA3zNRi6WXTE9Zgu7FGCvROEwgnjo1Y/wO0J6mXVXVx0tI8UThPT2Lg/uphJbCg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAylTUIfQd9wMWawaHF6La1G1bAvmRlxXe6L0XBrUIZiAiBIecpXTBhrbuYNw79/N8mmhJtKpS6K9iU5dEvD7LJXTw=="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.7.tgz_1472498884530_0.46114601590670645"}},"1.1.8":{"name":"mongo-dynamic-indexer","version":"1.1.8","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.8","scripts":{},"_shasum":"e7e1e135d0cf8b18ced92668cd94ecb2be46cc33","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"e7e1e135d0cf8b18ced92668cd94ecb2be46cc33","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.8.tgz","integrity":"sha512-WRe04gguXOUhE9eETlDUKvc4apmLRBUklKWHOjAb/FW7WqZo76A4w6/Ldnghtw//smPCYBxH4yamKFyw0PL+aQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCf5oTiQJUdiSoWqCw0nI7DN9QAKTLL3keNa9MSKBaGxgIgWLyNJnKyIPIW1CmfN6UiWW77D2KhOEE7tXlzdVL+SIU="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.8.tgz_1472745873494_0.9220374661963433"}},"1.1.9":{"name":"mongo-dynamic-indexer","version":"1.1.9","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.9","scripts":{},"_shasum":"ec621c6e70584cd8cad46522c46ac43044fff4bc","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"ec621c6e70584cd8cad46522c46ac43044fff4bc","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.9.tgz","integrity":"sha512-eDZ7B/q16vR0XNHzkVYDtb9wATx7OCv0JKZB5KQ9QAsO8sXLuOZw0AQzM+htqt6H/CBSfCiMJV0UoVGVp7UtpQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICVejMoQilu1zKB1oE8cNC6YPS3heINdTbeCV3j5cAVkAiEApfjG5T0/3xb88weit/qjK60rbQ8wQEeeVBS6RQVqQ9E="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.9.tgz_1472761502961_0.9334615264087915"}},"1.1.10":{"name":"mongo-dynamic-indexer","version":"1.1.10","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.10","scripts":{},"_shasum":"b508e61d4a55dec26ea1e79fa44c86bf0f79e657","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"b508e61d4a55dec26ea1e79fa44c86bf0f79e657","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.10.tgz","integrity":"sha512-Or170XYUFqa2wiqbMwjKpC+MT8S2xvrPio1Z4WkWq62nCLGR30lynsJDijTlrWz4TkQIH9doTi7E6Jjnp/1c4A==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDSIyweHdmG/HZjaqXbs5zS1khp/gCztJpo1x+a5y8pPQIgfiH+MKllgcf+zADclcKbWyMzYif0f2n50LF/UvUqMB8="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.10.tgz_1472857504956_0.6780837224796414"}},"1.1.11":{"name":"mongo-dynamic-indexer","version":"1.1.11","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.11","scripts":{},"_shasum":"58a1d9dcae72962533df9dd394568fbf7fa78588","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"58a1d9dcae72962533df9dd394568fbf7fa78588","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.11.tgz","integrity":"sha512-9PHkqTYxzkk4uejmugfWPfxj11vRAHDpOh7tSHpiPfVRYXLb8BtbvhUOGNZQyreLl1SfA2emZ7ZhljR3kR3mYQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID2oImJCCx6RhTcJtLN+DJg/oabXao5WYRlhr8sf9ju1AiEA64tleAFzEpIIeFjLlSicsqTRleCVVgmH1GmvziCkk+Y="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.11.tgz_1472861004809_0.13364449399523437"}},"1.1.12":{"name":"mongo-dynamic-indexer","version":"1.1.12","description":"Automatically selects and reccomends indexes for based on your Mongo queries.","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.12","scripts":{},"_shasum":"82c1c47d13b50ddb6f8117ada98d75229359d189","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"82c1c47d13b50ddb6f8117ada98d75229359d189","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.12.tgz","integrity":"sha512-RUgOFL1RM/0rlhT4WWQf/8BufR52WUuVj3kJAcXggeo/i03yfI88GWi6AYJwsNxUDFhkqcwOJkeuOFcCG8pUvQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBwb2pVmJpaKX+auZ7rA2we5IlBjcZpQQ0vb2/1BilI9AiA4LXCix8GzhfXPsIo2/0qIdmj46NdA8xKnacqWSf5V1Q=="}]},"maintainers":[{"name":"genixpro","email":"genixpro@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.12.tgz_1472861172900_0.9674559908453375"}},"1.1.13":{"name":"mongo-dynamic-indexer","version":"1.1.13","description":"Automatically selects and reccomends indexes based on your queries and data,","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.13","scripts":{},"_shasum":"eee3d76e0083004435f320482c0193e2fd83c073","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"eee3d76e0083004435f320482c0193e2fd83c073","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.13.tgz","integrity":"sha512-TICluC9X1A+8lZKnoxbCA/sPH4Y8rWwBnQjfoODUQAENR+KwI7FamyDe0Wl8Y4E3+pVu/eQJ5mX6c+kHpYB+kg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH7HNnW+jvA0+zwqkGeRlrqaKcYaBUU5LKj048MhNPKZAiEA9AMDxBfSkGBB1ma40XqnhSw5Dlgr8jNK6VI/LH/zWjM="}]},"maintainers":[{"name":"gabrielcastro","email":"npm@gabrielcastro.ca"},{"name":"genixpro","email":"genixpro@gmail.com"},{"name":"niksawtschuk","email":"nik@sawtschuk.com"},{"name":"sgiacomel","email":"simone@getsensibill.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.13.tgz_1473186392820_0.9902705883141607"}},"1.1.14":{"name":"mongo-dynamic-indexer","version":"1.1.14","description":"Automatically selects and reccomends indexes based on your queries and data,","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.14","scripts":{},"_shasum":"f4c5bafe3086f0a4a8fbe47397d12d75d43418a0","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"f4c5bafe3086f0a4a8fbe47397d12d75d43418a0","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.14.tgz","integrity":"sha512-D+7eTUFlFkeK6EY0ia6dEJX88+wj+ZZofmSKV802MH8Bq+NJy1Ei0vQ/79ljLK/QRyejmAd1+KADoYGrH3se7g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC+Belk1NWFrxDZho3jkOZSSqFVU52M7GaYlVyeWadx8QIgSakIFFiT38qFc5IBolT3hC4jHFybOljd/cGI14XV1vk="}]},"maintainers":[{"name":"gabrielcastro","email":"npm@gabrielcastro.ca"},{"name":"genixpro","email":"genixpro@gmail.com"},{"name":"niksawtschuk","email":"nik@sawtschuk.com"},{"name":"sgiacomel","email":"simone@getsensibill.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.14.tgz_1473189371148_0.3291599964722991"}},"1.1.15":{"name":"mongo-dynamic-indexer","version":"1.1.15","description":"Automatically selects and reccomends indexes based on your queries and data,","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.15","scripts":{},"_shasum":"c748f2303d3fea91f2504ae7102bc0237939aeb1","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"c748f2303d3fea91f2504ae7102bc0237939aeb1","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.15.tgz","integrity":"sha512-0ZCmUc8sqKvicm10Pm9RYVkA/O+8FEODSdSEObC3ZlQnWUzMenxukfZyIAAEIh59N2wbG6r9vzB09Yun8qohWA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHI8NPk+wEGU1ossAD8luzh2/I7JXqzwUAGN7YZsM23FAiEA0H2dlc+6nCOb7Gz3g7+hxdVuXnJqa+uXTBdblJFCZ2I="}]},"maintainers":[{"name":"gabrielcastro","email":"npm@gabrielcastro.ca"},{"name":"genixpro","email":"genixpro@gmail.com"},{"name":"niksawtschuk","email":"nik@sawtschuk.com"},{"name":"sgiacomel","email":"simone@getsensibill.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.15.tgz_1473778466210_0.8995094557758421"}},"1.1.16":{"name":"mongo-dynamic-indexer","version":"1.1.16","description":"Automatically selects and reccomends indexes based on your queries and data,","main":"index.js","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","dependencies":{"async":"^2.0.1","commander":"^2.9.0","farmhash":"^1.2.0","flat":"^2.0.1","mongodb":"2.2.x","mongodb-uri":"^0.9.7","underscore":"^1.8.3"},"bin":{"mongodynamicindexer":"./index.js"},"_id":"mongo-dynamic-indexer@1.1.16","scripts":{},"_shasum":"80834f7ceac071d9e105aef2cd8bd0e015c47a6a","_from":".","_npmVersion":"2.15.8","_nodeVersion":"4.4.7","_npmUser":{"name":"genixpro","email":"genixpro@gmail.com"},"dist":{"shasum":"80834f7ceac071d9e105aef2cd8bd0e015c47a6a","tarball":"https://registry.npmjs.org/mongo-dynamic-indexer/-/mongo-dynamic-indexer-1.1.16.tgz","integrity":"sha512-EIP1BHTZWw+8g94z81gaAbv6LIo6H3kl8Bc35OVWT8w5nNg2vZYvmwXe7sTrLjDNtPHSFrt3BVZZysbZ5LL1pg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCIKS+l/RP9ZXDEhyXwzLguKPZkPYYhcRDgZsoofC5wZAIgU4Ow6QjA4leJkKKkriCNlbAKUabjT2cYD8A2naLc9t4="}]},"maintainers":[{"name":"gabrielcastro","email":"npm@gabrielcastro.ca"},{"name":"genixpro","email":"genixpro@gmail.com"},{"name":"niksawtschuk","email":"nik@sawtschuk.com"},{"name":"sgiacomel","email":"simone@getsensibill.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/mongo-dynamic-indexer-1.1.16.tgz_1473784376151_0.6448308527469635"}}},"readme":"# Table of Contents\n\n- [Introduction](#introduction)\n- [License](#license)\n- [Quick Start](#quick-start)\n- [Command line Arguments](#command-line-arguments)\n- [Comparison with other tools](#comparison-with-other-tools)\n- [Fine Tuning Results](#fine-tuning-results)\n- [Modes of Usage](#modes-of-usage)\n    - [Static Analysis](#static-analysis)\n    - [Dynamic Service - Mongo Slow Query Profiling Mode](#dynamic-service---mongo-slow-query-profiling-mode)\n    - [Dynamic Service - Mongo full profiling mode with only recent query profiles](#dynamic-service---mongo-full-profiling-mode-with-only-recent-query-profiles)\n    - [As a library (under construction)](#as-a-library-under-construction)\n- [Query Metadata](#query-metadata)\n- [How does it pick indexes?](#how-does-it-pick-indexes)\n    - [Step 1: Collect and break down the queries](#step-1-collect-and-break-down-the-queries)\n    - [Step 2: Randomly sample the collection to statistics for each field](#step-2-randomly-sample-the-collection-to-statistics-for-each-field)\n    - [Step 3: Compute the optimal index for each query profile](#step-3-compute-the-optimal-index-for-each-query-profile)\n    - [Step 4: Eliminate indexes which are prefixes of other indexes](#step-4-eliminate-indexes-which-are-prefixes-of-other-indexes)\n    - [Step 5: Index Simplification - Randomly sample the collection for index statistics and eliminate unnecessary fields](#step-5-index-simplification---randomly-sample-the-collection-for-index-statistics-and-eliminate-unnecessary-fields)\n    - [Step 6: Index Extension](#step-6-index-extension)\n- [Troubleshooting](#troubleshooting)\n- [TODO](#todo)\n\n# Introduction\n\nThe Mongo Dynamic Indexer is a tool for automatically picking and maintaining indexes \nbased on the real queries being made to the database.\n\nIt is similar to the tool Dex, https://github.com/mongolab/dex, created by MongoLab.\nThe difference is that Dex was merely a tool to recommend indexes that you would later\nhand tune and modify with your own knowledge of your data.\n\nMongo Dynamic Indexer, on the other hand, is meant to be full service. It automatically\ntakes random samples of your data in order to help it determine the cardinality information\nfor each field, and for combinations of fields used to make up indexes. This allows\nMongo Dynamic Indexer to do a whole host of optimizations that other tools don't attempt,\nand the resulting indexes are just fantastic. They are minimalistic but still totally\ncover your queries.\n\n# License\n\nMongo Dynamic Indexer is licensed under MIT license. Please see the license file within\nthe distribution.\n\n# Quick Start\n\n## Install through NPM\n\nInstallation is quick and easy through npm.\n\n    $ npm install mongo-dynamic-indexer -g\n\n## Start the dynamic indexer\n\nStart the indexer pointing to your database. Note that, by default, it will enable profiling\non your database, so you must have that permission on the user you log in with.\n\n    $ mongodynamicindexer -d mongodb://localhost:27017/your_database -c -p 2\n\nYou could also just enable profiling manually, and use -p -1 so that the dynamic indexer will not change the profiling level:\n\n    $ mongo\n    MongoDB shell version: 2.6.10\n    connecting to: test\n    > db.setProfilingLevel(2)\n    { \"was\" : 0, \"slowms\" : 100, \"ok\" : 1 }\n    >\n\n## Use your system as you normally would\n\nNow you just use your system as you normally would! As queries come in, the Mongo Dynamic\nIndexer will record them. Every 60 seconds (change with -i), it will print out its recommended\nindexes and will make the changes (-c enables making the changes live).\n\n\n# Command line Arguments\n\n    $ mongodynamicindexer --help\n\n    Usage: mongodynamicindexer [options]\n    \n    Options:\n\n    -h, --help                                                   output usage information\n    -V, --version                                                output the version number\n    -d, --database <database>                                    The URI of the Mongo database which we will connect to. Must include the username and password.\n    -s, --sample-size <sample-size>                              The maximum number of documents to sample from a collection to determine cardinality information about fields on that collection, or indexes being proposed for that collection. Default is 100,000. Its highly recommended to keep this large.\n    --sample-speed <sample-speed>                                This is the number of seconds over which to sample a given collection. This is done so that we dont blast a database a ton of queries in a very short period of time. A lower number means faster speed. Default 10 minutes.\n    --minimum-cardinality <minimum-cardinality>                  The minimum number of distinct values a field should have in order to be included in an index. Default is 3. Set to 1 to disable this and include all fields.\n    --minimum-reduction <minimum-reduction>                      This is the amount that a field should narrow down results by in order to be considered worth having on the index. Default is 0.50, meaning that a field should, on average, remove at least 50% of the possible results to be considered worth having on the index. Setting this to 1 will disable the functionality. Please see the documentation for a better explanation of this functionality.\n    --no-index-extension <no-index-extension>                    This disables the index extension optimization.\n    -c, --do-changes                                             This tells the dynamic indexer that it should actually make the changes to the database that it recommends.\n    --collection <collection>                                    This is the collection which the dynamic indexer should use to store information on query patterns\n    -i, --interval <interval>                                    How often, in seconds, should the dynamic indexer make its recommendations\n    --cardinality-update-interval <cardinality-update-interval>  This is the number of days that cardinality information is valid for. Default 30 days.\n    --show-changes-only                                          If this is enabled, the script will only show the changes its making when synchronization, rather then a complete summary of all indexes.\n    -p, --profile-level <profile-level>                          This is the profiling level to set the database to. This is the same as Mongos profiling level, see https://docs.mongodb.com/manual/reference/command/profile/#dbcmd.profile. The default is 2, full profiling, but using 1 will enable slow-query-mode. If you set this to -1, the profiling level will not be changed from what it currently is.\n    -r, --recent-queries-only-days <recent-queries-only-days>    This is the number of days after seeing a query to forget about it. This ensures that queries that your code no longer peforms dont leave indexes around that you no longer need. By default this is set to -1, which means its disabled, meaning that old indexes will not get deleted unless you refresh the state of the dynamic indexer.\n    -m, --minimum-query-count <minimum-query-count>              This is the minimum number of times that a particular query needs to have happened before the dynamic indexer will create an index for it. Defaults to 1, which will create an index for any query.\n    --verbose                                                    Enable verbose output. Defaults to false. Can be helpful when trying to determine precisely why the system recommended the indexes that it did\n    --debug                                                      Enable debug mode. Debug mode will include line numbers with all the output\n    --simple                                                     Enable simple output mode. Instead of outputting a complete description of the index plan, it will instead just output the indexes raw. Easier for copying and pasting into your own code.\n\n\n# Comparison with other tools\n\nMongo Dynamic Indexer is far from the first tool to automatically recommend indexes for Mongo. However, it is the very first to do a whole host\nof optimizations that other tools don't do. See the comparison of the optimizations performed, and you will know that Mongo Dynamic Indexer\nwill produce excellent indexes for you!\n\n## Dex\n\n- Breaks apart queries into exact match, sort, and range portions\n- Automatically handles $or, $and, and $elemMatch conditions\n\n## Mongo Dynamic Indexer\n\n- Breaks apart queries into exact match, sort, and range portions\n- Automatically handles $or, $and, and $elemMatch conditions\n- Automatically sorts the exact-match and range fields by their cardinality. Highest cardinality first for exact match fields, lowest cardinality first for range fields.\n- Automatically handles parallel arrays by creating two separate indexes (Mongo does not support creating an index that has two separate array fields), see https://docs.mongodb.com/manual/core/index-multikey/#limitations\n- Automatically moves unindexable fields (due to length) into a separate \"hashed\" indexes\n- Allows you to automatically eliminate low-cardinality fields, such as booleans, from the resulting indexes\n- Automatically eliminates fields from indexes that don't add any additional specificity (by default, each additional field should narrow down results by at least 50%, most rules of thumb suggest 90% here). This particular optimization requires many passes of random sampling over your data, but its worth it!\n- Correctly handles multi-sort fields with different directions (sort {a:1, b:-1} can't use the index {a:1,b:1}, it must have {a:1,b:-1})\n- Automatically eliminates indexes which are just prefixes of other indexes (if you have {a: 1} and {a:1, b:1}, the first {a:1} index is totally superfluous)\n- Does multiple passes over the above algorithms to further ensure the most minimalistic effective set of indexes.\n- Allows you to filter out one-off queries that haven't occurred very often\n- Allows you to provide metadata about your query using $comment, so you can see exactly where in your code a particular index is coming from!\n\nAs you can see, Mongo Dynamic Indexer, while slower and requiring random sampling of your data, can produce way, way better results!\n\n# Fine Tuning Results\n\nThe main way to fine tune results is through the `--minimum-cardinality` and `--minimum-reduction` options.\n\n## If you want fewer resulting indexes, and more sharing of indexes between queries\n\n- Increase `--minimum-cardinality` so that low cardinality fields, like \"status\" or other enumerations, are eliminated from the base of the indexes. The default of `--minimum-cardinality 3` only eliminates boolean fields, since boolean fields have only 2 possible values. Raising it to `--minimum-cardinality 10` would eliminate more small enumerations and other fields with only a handful of values. Remember these fields are not deleted entirely from the indexes - they can be added back on in Step 6 of the optimization algorithm. Its simply that the system won't consider these fields when trying to see which queries can share indexes in Steps 4 and 5.\n- Decrease `--minimum-reduction` to eliminate fields that don't add much specificity to the index (often because they are highly correlated with other fields in the index). The default value of `--minimum-reduction 0.5` will only eliminate fields that, on average, narrow down the results less then 50%. Some blogs (such as https://emptysqua.re/blog/optimizing-mongodb-compound-indexes/#equality-range-sort ) suggest a rule of thumb of eliminating all fields that don't narrow results at least 90%. This would imply a value of `--minimum-reduction 0.1`. Remember that if you decrease this value, it would require more rounds of random sampling your data in order to determine the statistics. Be sure to adjust `--sample-speed` as needed.\n\n## If you want fewer indexes, eliminating indexes for queries that don't happen very often\n\n- Increase `--minimum-query-count` so that rare queries are filtered out and don't result in indexes\n\n## If you want more indexes that are more specific to their queries\n\n- Decrease `--minimum-cardinality`  to `--minimum-cardinality 1` will eliminate this optimization, including all fields in the base indexes generated by Step 3 of the algorithm.\n- Increase `--minimimum-reduction` up to a higher value then `--minimum-cardinality 0.5`, such as `--minimum-cardinality 0.85` or `--minimum-cardinality 1.00` to allow more fields to stay in the indexes, even if they don't add much specificity to the index.\n\n## If you want simpler indexes, that only have the minimum necessary fields\n\n- Use `--no-index-extension` to disable Step 6 of the optimization algorithm, which adds back fields to the resulting indexes that it eliminated in Steps 4 and 5\n\n\n# Modes of Usage\n\nThere are a bunch of different ways of installing and using the Mongo Dynamic Indexer,\nwith varying complexity and performance implications. \n\nMany of the cons of each of these modes could be alleviated by further development. Feel\nfree to contribute!\n\n\n## Static Analysis\n\nStatic analysis mode is the simplest possible way to deploy the dynamic indexer.\n\nIn this mode, you don't deploy the dynamic indexer as a service. Instead, you run set it\nup temporarily, and allow it to monitor the queries but don't allow it to make any changes.\n\nDuring this period, you might do a load test of some sort in order to get a fair sample of\ndifferent queries being made on your system.\n\nAfterwards, you take a look at its output and see the indexes that it recommends. You would\nthen hard-code these recommended indexes into your code base.\n\n### Steps\n\n#### Step 1 - Run the dynamic indexer in plain vanilla mode\n\n    mongodynamicindexer -d mongodb://localhost:27017/your_database -p 2\n\n#### Step 2 - Make a representative sample of queries in your system\n\nYou will need to perform a load test or something which sends a representative sample of \nqueries through the system. The dynamic indexer will print out its recommendations every\n60 seconds, but will not make any actual changes to the indexes.\n\nYou would then take these indexes and hard-code them in your application logic.\n\nIt is extremely important that both the data in your database, and the queries that you make\nduring the static analysis are consistent with what you will see in your production environment.\nIf you do this on a development machine with very little data, the statistical information on\nyour fields will not be very good, and thus the reccomended indexes will be bad.\n\n### Caveats\n\nSimilar caveats to the other profiling based modes.\n\n- Mongo has a habit of resetting the profiling level back to off when it restarts.\n  Therefore, you should ensure that if mongo restarts, mongodynamicindexer also \n  restarts so that it can reenable profiling when it starts.\n- Profiling only works on a single server. If you have the dynamic indexer enabled\n  on a specific server (primary or secondary), it will only see queries made on that\n  server! Therefore, the indexer should be enabled on the primary server. Sharding\n  is a whole other can of worms that is not supported in this mode.\n- The indexer should only be installed on one database server at a time!\n\n### Pros\n- You don't have to run profiling mode in production\n- Smallest performance impact\n- Least complexity - does not require installing a new service on your servers.\n  This can be done in an ad-hoc manner, and the recommendations put through your\n  normal database change process.\n\n### Cons\n- Quality of the resulting indexes depends entirely on the quality of the queries provided\n- Requires you to manually copy the indexes into your code\n- Unable to monitor actual queries to make sure that they are using the expected indexes.\n- Must be done manually on a regular basis to ensure that your indexes match your current\n  needs and queries.\n- If there is significant differences between the data that you test with, and the data\n  on the environments the indexes are actually being used on, then you will not get the\n  most optimal indexes. Particularly when it comes to field cardinality!\n\n\n## Dynamic Service - Mongo Slow Query Profiling Mode\n\nSlow Query Mode is the possible way of deploying the dynamic indexer as a service. Slow Query\nMode is easy to deploy and has low performance implications. Essentially, what we do is \nenable Mongo database profiling in 'slow query mode'. Every database query that takes\nover 100ms gets profiled. The dynamic indexer will then pick up an analyze that query,\nand create the necessary indexes to ensure that query goes quickly in the future.\n\nPlease see https://docs.mongodb.com/manual/tutorial/manage-the-database-profiler/ to learn\nmore about Mongos profiling mode.\n\n### Steps\n\n#### Step 1 - Delete your existing indexes\n\nThe dynamic indexer will not touch any existing indexes in the system. It will only \nmodify indexes whose name starts with \"auto_\", used to indicate that its an automatically\ncreated index managed by the mongo dynamic indexer.\n\nTherefore, you must delete your existing indexes. If you have unique or sparse indexes,\nyou may need to keep them because they affect the behaviour of your system. But you can\nsafely delete any indexes that you have only for performance\n\n    $ mongo\n    MongoDB shell version: 2.6.10\n    connecting to: test\n    > use mydatabase\n    switched to db mydatabase\n    > db.collection.dropIndexes()\n    {\n    \t\"nIndexesWas\" : 5,\n    \t\"msg\" : \"non-_id indexes dropped for collection\",\n    \t\"ok\" : 1\n    }\n\n\n#### Step 2 - Run the dynamic indexer with slow-query profiling enabled\n\n    mongodynamicindexer -d mongodb://localhost:27017/your_database -c -p 2\n\nNow in a live deployment of course, you would create this as a service on your system,\nusing something such as upstart or system-v.\n\n### Caveats\n\n- Mongo has a habit of resetting the profiling level back to off when it restarts.\n  Therefore, you should ensure that if mongo restarts, mongodynamicindexer also \n  restarts so that it can reenable profiling when it starts.\n- Profiling only works on a single server. If you have the dynamic indexer enabled\n  on a specific server (primary or secondary), it will only see queries made on that\n  server! Therefore, the indexer should be enabled on the primary server. Sharding\n  is a whole other can of worms that is not supported in this mode.\n- The indexer should only be installed on one database server at a time!\n\n### Pros\n- Only creates indexes for queries that are slow. This can prevent the system from creating\n  a bunch of indexes for queries that are performing well\n- Minimizes the performance impact in mongo compared to enabling profiling for every query\n- Captures all queries being made on your database\n\n### Cons\n- A single strange query can cause an index to be created permanently\n- Hard to use in complicated architectures involving sharding and replication\n- Can capture unexpected queries, like ones coming from the Mongo Shell\n- Unable to example queries to ensure that the expected index is being used\n\n\n## Dynamic Service - Mongo full profiling mode with only recent query profiles\n\nThis mode is similar to slow-query mode, except that you enable full profiling for all\nqueries. This has more of a performance implication, but has the benefit that you are\nnot keeping around indexes for queries that are no longer being made. It will only\nkeep around indexes for queries that have been made at least in the last N days, where\nN is configurable. \n\nPlease see https://docs.mongodb.com/manual/tutorial/manage-the-database-profiler/ to learn\nmore about Mongos profiling mode.\n\n### Steps\n\n#### Step 1 - Delete your existing indexes\n\nThe dynamic indexer will not touch any existing indexes in the system. It will only \nmodify indexes whose name starts with \"auto_\", used to indicate that its an automatically\ncreated index managed by the mongo dynamic indexer.\n\nTherefore, you must delete your existing indexes. If you have unique or sparse indexes,\nyou may need to keep them because they affect the behaviour of your system. But you can\nsafely delete any indexes that you have only for performance\n\n    $ mongo\n    MongoDB shell version: 2.6.10\n    connecting to: test\n    > use mydatabase\n    switched to db mydatabase\n    > db.collection.dropIndexes()\n    {\n    \t\"nIndexesWas\" : 5,\n    \t\"msg\" : \"non-_id indexes dropped for collection\",\n    \t\"ok\" : 1\n    }\n\n\n#### Step 2 - Run the dynamic indexer with regular profiling in recent query mode\n\n    $ mongodynamicindexer -d mongodb://localhost:27017/your_database -c -p 2 --recent-queries-only-days 14\n\nThe 14 here represents the number of days that is considered \"recent\".\n\nIn a live deployment, you would create this as a service on your system, using something \nsuch as upstart or system-v.\n\n### Caveats\n\nSimilar caveats to to slow query mode\n\n- Mongo has a habit of resetting the profiling level back to off when it restarts.\n  Therefore, you should ensure that if mongo restarts, mongodynamicindexer also \n  restarts so that it can reenable profiling when it starts.\n- Profiling only works on a single server. If you have the dynamic indexer enabled\n  on a specific server (primary or secondary), it will only see queries made on that\n  server! Therefore, the indexer should be enabled on the primary server. Sharding\n  is a whole other can of worms that is not supported in this mode.\n- The indexer should only be installed on one database server at a time!\n\n### Pros\n- Ensures that every single query made in your system is covered as best as possible by\n  a proper index.\n- Captures all queries being made on your database\n- Only creates indexes for queries that have actually been seen recently.\n- As your system evolves, your indexes will automatically evolve with it.\n- The dynamic indexer can examine profiling results and ensure that the expected indexes\n  are actually being used! This will allow you to pick out anomalies in your data\n  as well as flaws in mongo dynamic indexer.\n\n### Cons\n- Larger performance impact because of using mongo in full profiling mode\n- Might create more indexes then required to achieve good performance\n- Hard to use in complicated architectures involving sharding and replication\n- Can capture unexpected queries, like ones coming from the Mongo Shell\n\n### Side note - why not have both slow query mode AND recent query mode at the same time?\n\nThis will cause instability. Say you have a slow query:\n\n    {\"name\": \"brad\", \"email\": \"brad@example.com\"}\n\nAnd the dynamic indexer creates an index for it:\n\n    {name: 1, email: 1}\n\nWith these index now, the query is no longer slow! The dynamic indexer will no longer\nget notified that this query is being made. Thus, after 14 days (or whatever option you\nset), the index will automatically get deleted because the dynamic indexer doesn't believe\nthat query is being made anymore!\n\nOnce the index is gone, the query will become slow again. The dynamic indexer will see it\nonce again, and then that exact same index will get recreated.\n\n## As a library (under construction)\n\nIn this mode, you use the dynamic indexer as a library, and manually forward it the queries\nthat are being made on the system.\n\nThis gives you a lot more flexibility. For example, if you have a cluster deployment, you could\nforward all of the queries being made from all API servers through a message buffer like RabbitMQ\ninto a receiver process. This would ensure that you are actually getting all the queries being \nmade across your cluster. In the profiling mode, the only queries seen are the ones being made on\n*that* database server that the indexer is connected to.\n\nNOTE! This mode is not currently supported, it is a hypothetical mode that might be supported\nvery soon.\n\n### Pros\n- Ensures that you only capture queries of your choosing. Random queries being made on your\n  database by the Mongo shell will not have indexes created for them.\n- Can be used with recent-query mode\n- Allows more custom configuration of the expected performance for each query\n- Doesn't depend on Mongo profiling, so the performance is entirely within your control\n\n### Cons\n- Requires a lot of manual integration - significantly more development effort to buffer and\n  forward the queries being made.\n- Requires you to write an application in NodeJS\n\n# Query Metadata\n\nThe Dynamic Indexer is able to use metadata that attached to your queries through the use of $comment: https://docs.mongodb.com/manual/reference/operator/meta/comment/\n\nAll you need to do is attach a $comment to a particular query which contains a valid object. Any $comment which contains an object will be interpreted\nby the Dynamic Indexer as containing metadata intended for it. Any $comment which isn't an object (such as a string) will be ignored.\n\nFor example, from the Mongo shell, you might make a query that looks like this:\n\n    MongoDB shell version: 2.6.10\n    connecting to: test\n    > db.users.find({name: \"awesome person\", $comment: {source: \"shell.sh:1\"}})\n\nThe Dynamic Indexer will then be able to pick up this comment and use it to tell you where the query came from. The following are supported pieces of metadata:\n\n    {\n        source: \"string\"   // This is meant to specify where the query came from, such as the file and line number\n                           // or internal machine name. This can help you track down which indexes are coming from \n                           // where in your application.\n        version: \"string\"  // An additional optional piece of data that can go with \"source\". It allows you to track\n                           // which version of your application the query came from. Useful if you use file & line\n                           // numbers for 'source', since the exact line number changes when the source code is changed.\n    }\n\nCurrently this is the only piece of metadata supported. These sources will be shown in the summary of changes.\n\nAs an example, take a look at the following code for the Mongoose ORM for MongoDB in NodeJS. It adds in line numbers to every query made on a model object:\n\n    \"use strict\";\n    \n    const underscore = require('underscore');\n    \n    /**\n     * This function takes a mongoose model, the one created by mongoose.model(\"name\", schema),\n     * and wraps all of its query methods like find, findOne, update, etc... with versions that\n     * automatically add $comment to the query with some JSON specifying the source of the query -\n     * this can be used by the query optimizer to help us analyze the queries\n     */\n    module.exports.wrapQueriesWithMetadata = function wrapQueriesWithMetadata(model)\n    {\n        const packageContent = require('../package.json');\n        let version = \"\";\n        if (packageContent.version)\n        {\n            version = packageContent.version;\n        }\n    \n        function getCallerInfo()\n        {\n            const err = new Error();\n            const callingFrame = err.stack.split(\"\\n\")[3];\n            let callerInfo = callingFrame.substr(callingFrame.lastIndexOf(\"/\") + 1);\n            callerInfo = callerInfo.substr(0, callerInfo.lastIndexOf(\":\"));\n            return callerInfo;\n        }\n    \n        function wrapFunction(originalFunc)\n        {\n            return function ()\n            {\n                const args = Array.from(arguments);\n                let originalQuery = args[0];\n                if (!originalQuery)\n                {\n                    originalQuery = {};\n                }\n    \n                // Create a shallow clone that we can attach $comment to. This\n                // ensures that we don't unnecessarily modify the callers object\n                const query = underscore.extend({}, originalQuery);\n                query.$comment = {source: getCallerInfo(), version: version};\n    \n                // Write the modified query back to args\n                args[0] = query;\n    \n                return originalFunc.apply(model, args);\n            };\n        }\n    \n        model.find = wrapFunction(model.find);\n        model.findOne = wrapFunction(model.findOne);\n        model.findOneAndUpdate = wrapFunction(model.findOneAndUpdate);\n        model.count = wrapFunction(model.count);\n        model.update = wrapFunction(model.update);\n    };\n\n\n\n\n# How does it pick indexes?\n\nGreat question! There are a bunch of steps involved in order for the dynamic indexer to\nproduce its recommended indexes. \n\n\n## Step 1: Collect and break down the queries\nFirst, the dynamic indexer starts tailing the system.profile collection, watching queries\nlive as they happen.\n\nFor each query, it breaks it down all of the fields involved to a query profile consisting of 3 categories:\n\n- Exact match fields. E.g. {\"name\": \"bradley\"} contains an exact match for \"name\"\n- Sort fields. E.g. sorting on {\"birthday\": -1} would have the sort field \"birthday\"\n- Range / Multi-value fields. All manner of complex queries go here, such as $le, $gte, $regex, $neq, $elemMatch, $exists, $mod, and so forth. The reason is that all of these have these queries can produce multiple values.\n\nThe system also evaluates both sides of the $or as seperate queries, so a single query \nmight produce multiple query profiles. E.g. this query:\n\n    {\n        \"name\": \"bradley\",\n        \"$or\": [\n            {\n                email: {$exists: null}\n            },\n            {\n                status: \"registered\",\n                email: \"genixpro@gmail.com\"\n            }\n        ]\n    }\n    sort: {birthday: -1}\n\nWould produce two query profiles:\n\n    {\n        exact: [\"name\"],\n        sort: {\"birthday\": -1},\n        range: [\"email\"]\n    }\n\nand\n\n    {\n        exact: [\"name\", \"status\"],\n        sort: {\"birthday\": -1},\n        range: [\"email\"]\n    }\n\nIf you have a bunch of layers of nested $ors, then the number of resulting query profiles\ncan quickly become large.\n\nLesson: don't write insane queries! Remember: mongo actually has to evaluate your query.\nThe dynamic indexer can't index its way around your poor design.\n\nAt this stage we also filter out only query profiles that we have seen a minimum number of\ntimes. This minimum is set with `--minimum-query-count`. By default the minimum is 1, meaning\nit will recommend an index for every single query it sees, even if it only sees it once.\n\nOnly queries that meet the minimum will proceed to the next stage.\n\n## Step 2: Randomly sample the collection to statistics for each field\n\nAt this point, the system goes through the collection and grabs 1,000 random objects in\norder to determine cardinality and other information about each field.\n\nThe dynamic indexer will save the statistical information it collects for 30 days (by default),\nso it doesn't need to recompute it very often. This state is saved in a collection of its own,\nthe \"index-optimizer\" collection within your database. The collection will contain a single object\nwith the complete internal state of the dynamic indexer. If you need to reset the collection\nstatistics, you can go into the object and delete the \"sampler\" field and all its contents.\n\nThen restart the dynamic indexer and it will resample the database for statistical information.\n\n## Step 3: Compute the optimal index for each query profile\n\nNow, we need to compute the optimal index for each query profile. The system follows a few\nrules of thumb are as follows:\n\n- First, exact match fields, sorted by highest cardinality first\n- Then, sort fields in their exact sorting directions\n- Finally, all range/multi-value fields, sorted by lowest cardinality first\n\nSee https://emptysqua.re/blog/optimizing-mongodb-compound-indexes/#equality-range-sort and\nhttp://blog.mlab.com/2012/06/cardinal-ins/ for more information on how these rules were\nformulated. Neither of these blogs mention sorting the exact match fields by any specific\ncardinality. We simply have done this so that the order of fields is always consistent when\ncreating indexes. This allows more of the indexes to be folded into each other because they\nare index prefixes of each other - same performance but with fewer indexes! This gets\ndiscussed more later, in Step 4.\n\nThere are several additional things to consider, which the Mongo Dynamic Indexer is\nautomatically smart enough to handle.\n\n- not all fields are worth indexing\n- not all fields are even able to be indexed\n- some indexes can't even be created, because of limitations on mongo (such as indexes over\n  parallel arrays, see https://docs.mongodb.com/manual/core/index-multikey/#limitations)\n\nFields with very low cardinality, such as true/false values or fields with only a few\npossible enum values, might not be worth including in the index. This is particularly\ntrue if almost all of the objects in the database have the same few values for\na particular field. (Although the dynamic indexer is not yet smart enough to collect or\nuse statistical information on that level of detail. Feel free to contribute!)\n\nBy default (at the time of writing), the indexer will remove any fields with a \ncardinality lower then 3. For the most part, this will only eliminate boolean fields.\nHowever, you can raise this cardinality minimum using the --minimum-cardinality \noption on the command line. Remember this cardinality is based on computing the\nnumber of distinct values in the random sample of 1,000 objects taken from the database.\n\nNext, not all fields are even able to be indexed. Mongo has a hard limit that the\ncomplete size of all the indexed fields for a single entry must not exceed 1kb.\nTherefore, the dynamic indexer will consider any fields which have values that exceed\n1/2kb in size to be trouble. However, not all is lost! While these fields have to be\nremoved from the main index, there is still one thing that can be done. The dynamic\nindexer will create a separate \"hashed\" index for that field. This hashed index is \nable to support a few types of queries, such as exact match and $exists type queries, \nthus recuperating some of the lost speed.\n\nIf you see some single-field indexes that say \"hashed\", like {text: \"hashed\"} in your\nresults, know that its because you made a query on that field, but its unable\nto be indexed.\n\nLastly, for query profiles that would create an index involving two parallel arrays,\nan inherent limitation in Mongo, we create two separate indexes, one with each array.\nThis is the best that can be done in this case - Mongo should be able to use a Set\nintersection between both indexes sometimes, but that depends entirely on the query.\n\nAs an example, consider we have the following hypothetical object:\n\n    {\n        password: \"hashed_nonsense\",\n        names: [\n            {\n                first: 'brad',\n                last: 'awesome'\n            },\n                first: 'jillian',\n                last: 'awesome'\n            },\n                first: 'erica',\n                last: 'cool'\n            }\n        ],\n        statuses: [\n            {\n                date: Date(\"July 1, 2016\"),\n                status: \"active\"\n            },\n            {\n                date: Date(\"July 2, 2016\"),\n                status: \"active\"\n            }\n        ]\n    }\n\nAnd we tried to make a query that involved both the names array and statuses array:\n\n    {\"names.first\": \"brad\", \"statuses.date\": Date(\"July 2, 2016\"), password: \"hashed_nonsense\"}\n    \nIn theory, we would want the following index created:\n\n    {\"names.first\": 1, \"statuses.date\": 1, \"password\": 1}\n\nBut Mongo is unable to do this for you - it can not create indexes over two parallel \narrays. See https://docs.mongodb.com/manual/core/index-multikey/#limitations\n\nSo instead, the Mongo Dynamic Indexer will do the next best thing, which is to break\nit apart into two separate indexes, and let Mongo sort out the rest:\n\n    {\"names.first\": 1, \"password\": 1}\n    {\"statuses.date\": 1, \"password\": 1}\n\nAfter all of this is said and done, a single query profile will result in one or more\noptimized indexes. Given that with $or conditions, a single query can result in multiple\nquery profiles, and each query profile can require a number of indexes if you query\nof arrays, its easy to see that poorly written, overly complicated queries could balloon\ninto a bunch of required indexes to make it fast.\n\nLesson: the dynamic indexer can't index its way around your poor design. If you write \nqueries so complex where there is no possible way it could be done quickly, you should \nexpect that it is not executed quickly, even when its backed by several well chosen \nindexes. I can not repeat this enough.\n\n## Step 4: Eliminate indexes which are prefixes of other indexes\n\nNow the single most important step in terms of minimizing the total number of indexes,\nsince each index adds to the cost of your operation. Indexes which are an exact prefix\nof other indexes can be eliminated. Queries that only require the fields of the smaller\nindex can use the larger index with no penalty. For example, say you have the following\nindexes:\n\n    {\"name\": 1}\n    {\"name\": 1, \"status\": 1}\n    {\"name\": 1, \"email\": 1}\n    {\"email\": 1}\n    {\"email\": 1, \"status\" 1}\n    {\"name\": 1, \"email\": 1, \"status\" 1}\n    \nThere are several indexes that can be eliminated, because they are superfluous. \n{\"name\": 1} is a prefix of 3 other indexes:\n\n    {\"name\": 1, \"status\": 1}\n    {\"name\": 1, \"email\": 1}\n    {\"name\": 1, \"email\": 1, \"status\" 1}\n\nAnd thus can be eliminated. Similarly, {\"email\": 1} is an index prefix of a single\nindex:\n\n    {\"email\": 1, \"status\" 1}\n\nAdditionally, in a second stage of reduction, you can see that {\"name\": 1, \"email\": 1}\nis itself an index prefix of a longer index:\n\n    {\"name\": 1, \"email\": 1, \"status\" 1}\n\nThus, after the reduction step, we end can eliminate half of all the indexes we needed\nto create! We now only need: \n\n    {\"name\": 1, \"status\": 1}\n    {\"email\": 1, \"status\" 1}\n    {\"name\": 1, \"email\": 1, \"status\" 1}\n\nIn order to cover all 6 different query profiles!\n\n## Step 5: Index Simplification - Randomly sample the collection for index statistics and eliminate unnecessary fields\n\nHere is one of the most important steps in the process. In this stage, we take all of the \"optimal\"\nindexes recommended by the last reduction in Step 4, and then uses a random sample of data in order \nto calculate how much each successive field on the index narrows down the data. Fields which don't\nactually narrow down the data (because they might be highly correlated with fields earlier in the index) \ncan be eliminated. Sort fields are completely ignored in this calculation, since they are not used\nto narrow down results, only to sort the final results.\n\nThis can cause a lot more indexes to be eliminated, because it distills the indexes down to their\npurest essence, with the unnecessary fields removed. The main purpose of this is so that more queries\ncan be combined together to share indexes via Step 4.\n\nThis functionality can be disabled by using `--minimum-reduction 1`. This will ensure that\nall fields are kept on the index, regardless of whether they actually narrow down the\ndata any.\n\nAs an example, lets say you have the following objects:\n\n    {\"name\": \"brad\", birthday: \"june 3\"}\n    {\"name\": \"brad\", birthday: \"march 22\"}\n    {\"name\": \"anne\", birthday: \"september 6\"}\n    {\"name\": \"rebecca\", birthday: \"june 3\"}\n\nAnd the system initially proposes the following index:\n    \n    {\"name\": 1, \"birthday\": 1}\n\nThe system will now randomly sample the database to determine field statistics. It should end\nup with the following stats:\n\n    stats: name: 1.33/4=33.25%;   birthday: 1/1.33=75.00%;\n\nWhat its saying here is that, on average, the `name` field narrows the data down to about 33% of\nthe original entries. Adding on the `birthday` field only narrows down the data to 75% of those\nentries (on average). With the default settings, the system is now going to eliminate the birthday\nfield from the index - it simply doesn't narrow down the data enough. Once you have a persons name,\nyou've already pretty much narrowed it down to 1 object.\n\nAfter performing this step, the system will go back to Step 4 and perform index reduction, and then\ncome back to Step 5 to take another random sample. This is because we can only remove a single field \nat a time. When a field is removed from the index, you can't make any assumptions about what the \nstatistics for the smaller index will look like. By removing a field, the other fields become more\nimportant in providing the specificity the index needs. Thus, this step will only remove one field \nat a time, then do a reduction pass through Step 4, and then come back to Step 5 for another sample.\n\nIt will continue to repeat this until there are no more changes to be made. If you have a lot of very\nlarge data and you are making a lot of complicated queries that involve many fields, there can be\nmany passes between Step 4 and Step 5, each sampling 100,000 objects. It can take a long time. \nEven setting `--sample-speed 1`, it can still be several hours of back and forth in order for the\ndynamic indexer to resolve to the absolute most optimal indexes. Don't worry, its worth it.\n\nAs you can see, this step can enormously cut down on the total number of indexes recommended\nby the system, particularly if there is a lot of correlation between your various fields.\nDepending on your data, however, this might end up being too aggressive - folding too many queries\ntogether. If thats the case, try increasing `--minimum-reduction` above 0.5, to 0.8 and 0.9, so \nthat it allows more fields through even if they don't reduce that much.\n\n\n## Step 6: Index Extension\n\nSteps 4 and 5 will, in combination, do a great job at finding which queries can share indexes. Their\nprimary purpose is to ensure that we don't end up generating hundreds of different indexes just because\nyou make a great diversity of different queries. They distill each query down to the most important fields,\nand ensures maximal reuse of indexes.\n\nHowever, its possible that the removal of fields by Step 5, (and also by the cardinality minimums in Step 3)\nhave gone too far - they have resulted in general purpose indexes that don't fully cover the most important\nqueries in your system.\n\nSo by this stage, we already know how many resulting indexes we are going to have and which queries\nthose indexes are intended to cover. So now we ask, for a given index, is it possible to add any fields\nto the end of the index.\n\nIn order to choose what fields to tag onto the end of the index, it just goes to each query profile and\nlooks at eligible fields. An eligible field is an exact-match or range-match field that was removed\nduring Steps 3 or 5. It will add the field which is used by the most query profiles based on their\nusage-count - e.g. it will add in the field that would be useful by the most queries. If two fields\nhave exactly the same usage-count, then it will add the highest cardinality fields first.\n\nAlthough these additional fields might not narrow down the results by any significant extend (and you\nwill see that in the index statistics), they serve two useful purposes:\n\n- They send a stronger signal to Mongo that it should use that index for those queries. For example, when an index totally covers a query, Mongo will straight to using it without generating alternatives.\n- In some cases they can improve the performance, particularly when there is a lot of rounding error because the number of objects you are sampling is small relative to the diversity of your data\n\nYou might ask, why go to all the effort to be minimalistic by removing fields in Steps 3 to 5, only\nto add those fields back on in this Step. The reason is that Steps 3-5 are concerned with figuring out\nwhich queries could share which indexes, in order to produce the smallest set of indexes that completely\ncover your queries. Otherwise, the system might end up recommending 250 different indexes if you have\n250 different queries. Steps 3-5 have the effect of moving the *most important* fields to the front\nof the index. Step 6 adds back on unimportant fields in order to get whatever performance gain\nthey can reap.\n\nIt should be noted that this is not guaranteed to improve results - although you won't end up with\nmore indexes because of this step, you will end up with larger indexes because of the additional fields.\nYou can disable this step by using --no-index-extension if you just want the minimalistic indexes\nwithout the extensions. The minimalistic indexes should give you great performance - this step is just\nmeant to add an extra 10% for certain edge cases.\n\n\n# Troubleshooting\n\n## Error: MongoError: No more documents in tailed cursor\n\nPlease ensure that you have database profiling enabled, and that you have made at least one\nquery. Otherwise, the profiling collection will be empty, resulting in this error.\n\nYou must restart the program after receiving this error.\n\n## I am getting no output\n\nPlease ensure that database profiling is enabled.\n\nThis can also happen if you run the program with --show-changes-only, and you already\nhappen to have all of the indexes you need.\n\n## What are all these indexes with 0 query profiles?\n\nThese are the indexes that the program found that it is not managing. It will *not*\ndelete your existing indexes for you. Any and all indexes that are created outside\nthe dynamic indexer will be left *as-is*. This allows you the freedom to combine\nyour own indexes with the ones that dynamic indexer recommends.\n\nIf you want to give total control to the dynamic indexer, you should delete these\nexisting indexes!\n\nNote that currently, there is one exception to this which is if your index name \nbegins with \"auto_\", such as when you are indexing a field \"auto\". The prefix\n\"auto_\" is how the dynamic indexer knows a particular index is one that its managing,\nso it could get confused in this one case.\n\n## How do I reset the internal state of the dynamic indexer?\n\nDelete the data in the `index-optimizer` collection which is used by the dynamic indexer\nto hold its internal state. Alternatively, you can just delete the `querySet` or\nthe `sampler` fields on the object it creates in that collection, if you just want to\nreset the known queries or sampling data without resetting the other.\n\n## Can I copy the internal state of the dynamic indexer between databases?\n\nYes as long as the database name is the same.\n\nIf the database name changes, then no, at least not yet. We have to change a bunch of places\nin the dynamic indexer code which uses `namespace` to just use `collectionName` in order\nto allow this. Feel free to contribute!\n\n\n# TODO\n\n## General\n- Put an eslint file into the repository.\n- Rename everything about 'range' matches to 'multivalue' matches\n\n## Documentation to write\n- Dependencies re: packages, mongo versions\n\n## General Features\n- The sampling for index statistics could be significantly improved:\n    - When sampling, if its computing cardinalities for the same prefix (but for different indexes), then it should share the computation in memory\n- Gather statistics on how often each index is used, so we know which indexes are the most important\n- Need a way to trigger index synchronization only at 4am\n- Logging using syslog\n\n## Library\n- Refactor the various classes in the application so that it can be used in a flexible manner as a library. The application should just use the library and weave it into a whole.\n- A way for it to $hint to mongo which index it should use (at least for comparison with mongos internally chosen index)\n- Should be able to automatically wrap mongoose and native mongodb objects (or maybe only native mongodb) and provide things like line numbers in $comment metadata automatically\n\n## Optimization improvements\n- Would be nice if you could provide a configuration file for optimization, as using the command line gets a bit tedious when many optimizations are involved\n    - In the configuration file, you might be able to specify a list of fields to ignore for the purposes of indexing\n- (Maybe) In certain cases, it might be permissible to allow some $in's and other queries to be called 'exact' instead of multi if there is only a couple of values being matched against\n- Might want to break up multi-match fields into two different priority levels, e.g. $in's with only a couple of values would be ranked higher then $lt or $gt with many values\n- Any field with a Buffer object should automatically be a 'hashed' field (should be able to turn this on/off)\n- Need to refactor so that there is more \"componentization\" of the various optimizations, so that they can independently be turned on and off and configured, possibly even rearranged where permitted.\n    - Possibly a design where an optimization component can hook at different stages of the process, such as creating the query profile, creating naive indexes, creating optimized indexes, and rearranged and reducing indexes.\n- Would be nice if it could analyze your data and your queries and try to recommend shard keys, or at least analyze ones that you provide. A general understanding of sharding would be good for index selection would also be good.\n- Able to have dynamic cardinality minimums. E.g. a query profile first generates indexes with only high cardinality fields, but gradually allows in more fields if the queries for that profile don't meet the speed requirements\n- One identified issue is that a lot of indexes seem to get created where a field might be done as an exact match sometimes and a range match other times. It would be nice to be able to say 'fuck it' and make them all range-matches in some of these cases, to avoid extra indexes.\n- Perhaps there needs to be a way of ranking indexes by how important they are. This way you could say you have an upper limit of 30 indexes, and the system will do the best it can to choose 30 indexes that cover all your queries.\n- There are some cases where, if we arranged the fields in a different way then by the cardinality minimum, we can sometimes fold more indexes into each other.\n    For example, say we have two queries:\n        {a:'ok'}\n        {a:'ok', b: 'test'}.\n    Lets say that A is low cardinality and B is high cardinality. With the current settings, the system will then recommend two indexes:\n        {a: 1}\n        {b: 1, a: 1}\n    Because by default, exact matches are sorted by highest cardinality to lowest cardinality, and only after is index reduction performed.\n\n    In this scenario, we would like the system to be smart enough to rearrange the fields so that you can use just one index:\n        {a: 1, b: 1}\n\n    There are a bunch of potential scenarios like this with both the exact and range matches to reduce the number of resulting indexes.\n\n","maintainers":[{"email":"nik@sawtschuk.com","name":"niksawtschuk"},{"email":"simone@getsensibill.com","name":"sgiacomel"},{"email":"npm@gabrielcastro.ca","name":"gabrielcastro"}],"time":{"modified":"2022-06-20T05:45:18.738Z","created":"2016-08-11T15:48:06.718Z","1.0.0":"2016-08-11T15:48:06.718Z","1.0.1":"2016-08-11T17:08:16.788Z","1.0.2":"2016-08-11T17:51:38.875Z","1.0.3":"2016-08-12T15:44:07.720Z","1.0.4":"2016-08-15T22:33:21.246Z","1.0.5":"2016-08-17T17:19:44.353Z","1.0.6":"2016-08-17T17:50:39.763Z","1.0.7":"2016-08-18T17:41:44.132Z","1.0.8":"2016-08-18T21:06:18.634Z","1.0.9":"2016-08-23T19:19:40.774Z","1.1.0":"2016-08-25T16:44:49.395Z","1.1.1":"2016-08-25T18:41:17.865Z","1.1.2":"2016-08-25T18:58:02.636Z","1.1.3":"2016-08-25T19:21:13.579Z","1.1.4":"2016-08-26T17:26:02.473Z","1.1.5":"2016-08-29T14:53:57.422Z","1.1.6":"2016-08-29T17:06:22.186Z","1.1.7":"2016-08-29T19:28:05.862Z","1.1.8":"2016-09-01T16:04:35.595Z","1.1.9":"2016-09-01T20:25:05.084Z","1.1.10":"2016-09-02T23:05:05.195Z","1.1.11":"2016-09-03T00:03:25.074Z","1.1.12":"2016-09-03T00:06:16.795Z","1.1.13":"2016-09-06T18:26:34.035Z","1.1.14":"2016-09-06T19:16:12.391Z","1.1.15":"2016-09-13T14:54:28.629Z","1.1.16":"2016-09-13T16:32:58.618Z"},"homepage":"https://bitbucket.org/sensibill/mongo-dynamic-indexer#readme","repository":{"type":"git","url":"git+https://bitbucket.org/sensibill/mongo-dynamic-indexer.git"},"author":{"name":"Sensibill Inc"},"license":"MIT","readmeFilename":"README.md"}