TylerBrock / mongo-hacker

MongoDB Shell Enhancements for Hackers
tylerbrock.github.io/mongo-hacker
MIT License
1.79k stars 235 forks source link

Proposal: Add console.table() polyfill #202

Closed gianpaj closed 7 months ago

gianpaj commented 5 years ago

Summary

Adding a function that will display table for JSON objects and types coming from query results.

Perhaps:

> db.users.find({}, {username:1 , _id:0 }).table()
┌─────────┬─────────────┐
│ (index) │  username   │
├─────────┼─────────────┤
│    0    │   'mark'    │
│    1    │ 'hryhoriew' │
│    2    │   'serge'   │
│    3    │   'skyor'   │
│    4    │  'pvlshop'  │
└─────────┴─────────────┘

Motivation

Sometimes you have fairly simple data and you'd like to visualise in a table format.

Example

For example, a list of users:

$ db.users.find({}, {username:1, emailAddress: 1,createdAt:1, accountStatus:1, _id:0 }).sort({createdAt: -1}).limit(5)
{
  "accountStatus": "verified",
  "username": "use323",
  "emailAddress": "use3aa@gmail.com",
  "createdAt": ISODate("2019-03-31T20:50:54.846Z")
}
{
  "accountStatus": "verified",
  "username": "use33",
  "emailAddress": "asdf@icloud.com",
  "createdAt": ISODate("2019-03-31T20:50:37.885Z")
}
{
  "accountStatus": "verified",
  "username": "use3",
  "emailAddress": "asdf@gmail.com",
  "createdAt": ISODate("2019-03-31T20:48:40.759Z")
}
{
  "accountStatus": "verified",
  "username": "use3",
  "emailAddress": "asdf@gmail.com",
  "createdAt": ISODate("2019-03-31T20:46:38.573Z")
}
{
  "accountStatus": "verified",
  "username": "asdf1",
  "emailAddress": "asdf@gmail.com",
  "createdAt": ISODate("2019-03-31T20:43:16.290Z")
}

The ugly version is not that much better:

db.users.find({}, {username:1, emailAddress: 1,createdAt:1, accountStatus:1, _id:0 }).sort({createdAt: -1}).limit(5).ugly()
{ "accountStatus": "verified", "username": "asdf", "emailAddress": "asdf@gmail.com", "createdAt": ISODate("2019-03-31T20:50:54.846Z") }
{ "accountStatus": "verified", "username": "asdf", "emailAddress": "21asdf@icloud.com", "createdAt": ISODate("2019-03-31T20:50:37.885Z") }
{ "accountStatus": "verified", "username": "dfswer", "emailAddress": "dddas@gmail.com", "createdAt": ISODate("2019-03-31T20:48:40.759Z") }
{ "accountStatus": "verified", "username": "tert", "emailAddress": "asdf@gmail.com", "createdAt": ISODate("2019-03-31T20:46:38.573Z") }
{ "accountStatus": "verified", "username": "zczx", "emailAddress": "asdf1@gmail.com", "createdAt": ISODate("2019-03-31T20:43:16.290Z") }

Node JS (tested on v10.13) it has console.table:

> console.table(a)
┌─────────┬───────────────┬──────────┬───────────────────┬──────────────────────────┐
│ (index) │ accountStatus │ username │   emailAddress    │        createdAt         │
├─────────┼───────────────┼──────────┼───────────────────┼──────────────────────────┤
│    0    │  'verified'   │ 'asdf2'  │ 'dsaf@gmail.com'  │ 2019-03-31T20:50:54.846Z │
│    1    │  'verified'   │ 'bvnm65' │ 'qwe@icloud.com'  │ 2019-03-31T20:50:37.885Z │
│    2    │  'verified'   │ 'yuio7'  │ 'erwwe@gmail.com' │ 2019-03-31T20:48:40.759Z │
│    3    │  'verified'   │ 'asdf23' │ 'gdfh@gmail.com'  │ 2019-03-31T20:46:38.573Z │
│    4    │  'verified'   │ 'afasd2' │ 'xcvb@gmail.com'  │ 2019-03-31T20:43:16.290Z │
└─────────┴───────────────┴──────────┴───────────────────┴──────────────────────────┘

Detailed design

Alternatives

TBD

Unresolved questions

Working prototype

I adapted this project (konsole.table) and loaded the JS file in the mongo shell:

$ mongo consoletable.js  --shell

> table(db.users.find({}, {username:1, emailAddress: 1,createdAt:1, accountStatus:1, _id:0 }).sort({createdAt: -1}).limit(5).toArray())
─────────────────────────────────────────────────────────────────────────────────────────────────────────
│ (index)  │ accountStatus  │ createdAt                                 │ emailAddress       │ username  │
─────────────────────────────────────────────────────────────────────────────────────────────────────────
│ 0        │ "verified"     │ Sun Mar 31 2019 23:50:54 GMT+0300 (EEST)  │ "dsaf@gmail.com"   │ "asdf2"   │
│ 1        │ "verified"     │ Sun Mar 31 2019 23:50:37 GMT+0300 (EEST)  │ "qwe@icloud.com"   │ "bvnm65"  │
│ 2        │ "verified"     │ Sun Mar 31 2019 23:48:40 GMT+0300 (EEST)  │ "erwwe@gmail.com"  │ "yuio7"   │
│ 3        │ "verified"     │ Sun Mar 31 2019 23:46:38 GMT+0300 (EEST)  │ "gdfh@gmail.com"   │ "asdf23"  │
│ 4        │ "verified"     │ Sun Mar 31 2019 23:43:16 GMT+0300 (EEST)  │ "xcvb@gmail.com"   │ "afasd2"  │
─────────────────────────────────────────────────────────────────────────────────────────────────────────

here is the code so far: https://gist.github.com/gianpaj/63e04baed150f30b8976c16b16a0010c

To get this to work:

db.users.find(/*...*/).table()

Add the following to the .mongorc.js file:

DBQuery.prototype.table = function() {
  table(this.toArray());
  return;
};

and then run this:

$ mongo consoletable.js  --shell

I'll be happy to make a PR after there're enough people interested