RFC: NoSQL Schema Sampling RFC

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9603
GitOrigin-RevId: b7029b9ddf38086cc05002631c844eff91efd70f
This commit is contained in:
Martin Mark 2023-06-20 09:23:48 -04:00 committed by hasura-bot
parent a394510252
commit f6ac976bda
15 changed files with 76434 additions and 0 deletions

View File

@ -0,0 +1,42 @@
version: '3'
services:
# External MongoDB sample database
mongodb:
image: mongo:6
container_name: mongodb_mongo
ports:
- 27017:27017
volumes:
# Imports sample database:
- ./sample_data/import.sh:/docker-entrypoint-initdb.d/import.sh
- ./sample_data/sample_mflix:/sample_data/sample_mflix
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
healthcheck:
test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
interval: 5s
timeout: 10s
retries: 5
start_period: 10s
# External service which will be used for sampling
mongodb_sampler:
image: node
container_name: mongodb_sampling
environment:
MONGO_DATABASE: mongodb://root:password@mongodb:27017/sample_mflix
MONGO_USERNAME: root
MONGO_PASSWORD: password
MONGO_SELECT_COLLECTIONS: '' # which collections to analyze and sample. ('' [all collections]), (movies,comments)
MONGO_UPDATE_COLLECTIONS: true # automatically update collections in database with validation schemas. (true or false [or blank])
volumes:
# Scripts to analuze the database and create the validation schema:
- ./schema_sampler:/schema_sampler
# Final results will be stored here:
- ./schema_exports:/schema_exports
command: bash -c "/schema_sampler/analyze.sh"
depends_on:
mongodb:
condition: service_healthy

View File

@ -0,0 +1,81 @@
# RFC: NoSQL sampling for automatic schema generation
As we operate in an environment encompassing both SQL and NoSQL databases, the inherent unstructured nature of NoSQL presents specific challenges.
Despite the flexibility and scalability advantages of NoSQL databases, managing data efficiently becomes a complex task, particularly in the context of ensuring a predictable API and improved coding ergonomics.
## Problems / description
- **Inherent unstructured nature of NoSQL**: NoSQL databases, such as MongoDB, lack a predefined schema. This feature, while enabling flexibility, complicates the definition and management of data.
- **GraphQL provides guardrails, but requires structure**: GraphQL introduces un-opinionated guardrails around the NoSQL data source. Our approach provides type safety, enhances execution performance, enables predictable APIs, and improves coding ergonomics.
- **Ease and speed of onboarding**: The current state renders onboarding with GraphQL and NoSQL databases a complex process. The absence of a predefined schema in NoSQL databases makes it harder for newcomers to "plug-in" their data sources the same way they would with SQL databases.
- **Limited used of validation schema**: One of our current solutions is to use the validation schema in MongoDB. However, this solution is not widely used by our users.
- **Feature parity**: Providing users with capabilities to instantly introspect and track their Collections and Documents across MongoDB databases can expedite their onboarding process with Hasura and elevate NoSQL databases to feature parity with other schema-based databases supported by Hasura.
## Proposed solution
To address these challenges, the proposal is for an automatic schema generation tool leveraging NoSQL sampling techniques is proposed.
A proof-of-concept is below for MongoDB, and the same approach can be applied to other NoSQL databases.
Essentially, the idea around is that we can use sampling to take either the entire, or a subset of a collection's documents.
Then we would run an analysis to get an idea about the shapes and types that are found within the universe of documents in the schema. Then we would use that analysis to generate a schema which could be used as an onboarding starting point to power the GraphQL schema in Hasura.
This schema would then be customizable to allow for changes as needed by the end-user.
## Open questions
- What kind of selectors are necessary to be able to select the right documents?
- For example in MongoDB, we have the ability to select documents based on a query, maxed depth, based on a percentage of the collection, or based on a max number of records.
- How should the tooling select which type to use when there are conflicting types?
- For example, if a certain field has majority `int` types and a couple of `string` types, which should be taken?
- Would this need to be configurable?
- When authoring the schema, should we have the option
- For example, certain situations where very few optional embedded-objects which are contained only in a few records in a collection.
- Should we have something like a 'must have been found in x % of documents' setting?
- Should this be implemented into core tools, or is there a flexibility in being able to have this as part of an external set of tools?
- How can this be implemented in a way which is reproducible for other NoSQL database vendors.
-----
## Proof-of-concept
We've created a proof of concept for a schema sampler that can be run against a MongoDB database.
It's built using a combination of **mongosh** (https://www.mongodb.com/docs/mongodb-shell/), **Variety** MongoDB schema analyzer (https://github.com/variety/variety), and Node.js.
It generates a MongoDB validation schema based on the analysis of the documents in the collection, and then optionally will apply it to the database.
*[Later this same work can be used for generating Hasura-representations of the schema using our logical models as well.]*
That schema can then be used by Hasura to generate a GraphQL schema on top of the MongoDB datasource.
### How do I get started
- `docker compose up`
- Runs MongoDB and loads up the `sample_mflix` sample database.
- Has a healthcheck so the sampler shouldn't run till the database is ready.
- Sampler runs `/schema_sampler/archive.sh` which bootstraps introspecting the collections, running them through variety, converting the analysis to a validation schema, and then updating that schema back into MongoDB.
### How can I customize what is being introspected and sampled?
The docker container currently contains some environment variables below which can be used for selecting the collections to analyze and sample.
If you'd like to customize the sampling method, you can edit the `./schema_sampler/analyze.sh` file.
On line 29 there's:
```bash
mongosh ${MONGO_DATABASE} --quiet --eval "var collection = '${collection//\'/}', outputFormat='json'" --username ${MONGO_USERNAME} --password ${MONGO_PASSWORD} --authenticationDatabase=admin /schema_sampler/variety.js > "/schema_exports/analysis/${collection//\'/}.json"
```
which is where the data is retrieved for sampling using `mongosh`. You can edit the `--eval` command to change the sampling method (for example, adding a `find()` to only records using version of a schema, or a `limit()` to only return the first 5000 records).
### Want to know more about what's happening
Running `docker logs mongodb_sampling` would allow you to see what was run when inside the sampling container.
### ./schema_exports volume mount
Will contain the intermediate analysis files and JSON files for the validation schema export.
### Docker environment variables
The `mongodb_sampler` container has a few environment variable helpers which you can set:
- `MONGO_DATABASE`: The MongoDB connection string.
- `MONGO_USERNAME`: The MongoDB username.
- `MONGO_PASSWORD`: The MongoDB password.
- `MONGO_SELECT_COLLECTIONS`: Which collections to analyze and sample. ('' [for all collections]), (movies,comments)
- `MONGO_UPDATE_COLLECTIONS`: Automatically update collections in the database with the generated validation schemas. (true or false [or blank for false])

View File

@ -0,0 +1,10 @@
#!/bin/bash
# MFlix Dummy Data
echo "📡 Importing mflix sample data..."
mongoimport --host localhost:27017 --username root --password password --authenticationDatabase=admin --db sample_mflix --collection comments --file /sample_data/sample_mflix/comments.json
mongoimport --host localhost:27017 --username root --password password --authenticationDatabase=admin --db sample_mflix --collection movies --file /sample_data/sample_mflix/movies.json
mongoimport --host localhost:27017 --username root --password password --authenticationDatabase=admin --db sample_mflix --collection sessions --file /sample_data/sample_mflix/sessions.json
mongoimport --host localhost:27017 --username root --password password --authenticationDatabase=admin --db sample_mflix --collection theaters --file /sample_data/sample_mflix/theaters.json
mongoimport --host localhost:27017 --username root --password password --authenticationDatabase=admin --db sample_mflix --collection users --file /sample_data/sample_mflix/users.json
echo "✅ Mflix sample data imported..."

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,186 @@
email,points_total,points_wallet,tier
aidan_gillen@gameofthron.es,371118,92780,Gold
harry_lloyd@gameofthron.es,243542,81181,Silver
michelle_fairley@gameofthron.es,301074,301074,Silver
kit_harington@gameofthron.es,840961,210240,Silver
sophie_turner@gameofthron.es,896887,298962,Silver
maisie_williams@gameofthron.es,232576,116288,Silver
richard_madden@gameofthron.es,888334,888334,Silver
alfie_allen@gameofthron.es,328439,65688,Gold
isaac_hempstead_wright@gameofthron.es,55755,11151,Silver
mark_addy@gameofthron.es,760455,380228,Silver
rory_mccann@gameofthron.es,921802,921802,Silver
sean_bean@gameofthron.es,121698,121698,Silver
jack_gleeson@gameofthron.es,522857,174286,Silver
nikolaj_coster-waldau@gameofthron.es,311769,311769,Silver
iain_glen@gameofthron.es,892838,446419,Silver
jason_momoa@gameofthron.es,886541,295514,Silver
lena_headey@gameofthron.es,376561,125520,Silver
peter_dinklage@gameofthron.es,604113,302057,Silver
jerome_flynn@gameofthron.es,130830,43610,Silver
emilia_clarke@gameofthron.es,212897,212897,Silver
conleth_hill@gameofthron.es,382143,382143,Silver
sibel_kekilli@gameofthron.es,183257,36651,Silver
charles_dance@gameofthron.es,237769,59442,Silver
james_cosmo@gameofthron.es,483039,483039,Silver
rose_leslie@gameofthron.es,268091,268091,Silver
joe_dempsie@gameofthron.es,756231,252077,Silver
kristofer_hivju@gameofthron.es,218877,43775,Silver
oona_chaplin@gameofthron.es,981827,327276,Silver
natalie_dormer@gameofthron.es,101141,33714,Silver
hannah_murray@gameofthron.es,278877,278877,Silver
gwendoline_christie@gameofthron.es,47643,11911,Silver
iwan_rheon@gameofthron.es,10021,5011,Silver
michiel_huisman@gameofthron.es,748972,149794,Silver
indira_varma@gameofthron.es,453672,113418,Silver
liam_cunningham@gameofthron.es,7458,3729,Silver
john_bradley-west@gameofthron.es,268615,67154,Silver
nathalie_emmanuel@gameofthron.es,581997,145499,Silver
stephen_dillane@gameofthron.es,963996,963996,Silver
dean-charles_chapman@gameofthron.es,428911,214456,Silver
jonathan_pryce@gameofthron.es,315519,105173,Silver
natalia_tena@gameofthron.es,368297,92074,Silver
carice_van_houten@gameofthron.es,829341,207335,Silver
mark_stanley@gameofthron.es,37041,7408,Silver
art_parkinson@gameofthron.es,784606,392303,Silver
esme_bianco@gameofthron.es,447069,223535,Silver
hafthór_júlíus_björnsson@gameofthron.es,498905,124726,Silver
dominic_carter@gameofthron.es,734054,734054,Silver
kristian_nairn@gameofthron.es,979762,244941,Silver
nell_tiger_free@gameofthron.es,554970,138743,Silver
donald_sumpter@gameofthron.es,306128,61226,Silver
ron_donachie@gameofthron.es,691770,230590,Silver
eugene_simon@gameofthron.es,903412,903412,Silver
amrita_acharia@gameofthron.es,331518,110506,Silver
ian_mcelhinney@gameofthron.es,428641,428641,Silver
ian_gelder@gameofthron.es,880463,220116,Silver
roxanne_mckee@gameofthron.es,913367,913367,Silver
tom_wlaschiha@gameofthron.es,806067,161213,Silver
michael_mcelhatton@gameofthron.es,712946,237649,Silver
julian_glover@gameofthron.es,729666,364833,Silver
ian_beattie@gameofthron.es,829971,414986,Silver
finn_jones@gameofthron.es,41975,8395,Silver
ben_hawkey@gameofthron.es,919040,229760,Silver
richard_dormer@gameofthron.es,760838,380419,Silver
brian_fortune@gameofthron.es,227457,75819,Silver
daniel_portman@gameofthron.es,860359,286786,Silver
gemma_whelan@gameofthron.es,576875,144219,Silver
ben_crompton@gameofthron.es,138273,46091,Silver
tara_fitzgerald@gameofthron.es,715873,143175,Silver
jacob_anderson@gameofthron.es,310174,310174,Silver
anton_lesser@gameofthron.es,742440,247480,Silver
diana_rigg@gameofthron.es,371490,185745,Silver
kerry_ingram@gameofthron.es,391027,97757,Silver
ellie_kendrick@gameofthron.es,78367,15673,Silver
peter_vaughan@gameofthron.es,604767,604767,Silver
josef_altin@gameofthron.es,243760,121880,Silver
owen_teale@gameofthron.es,88378,17676,Silver
thomas_brodie-sangster@gameofthron.es,532844,266422,Silver
greg_powell@fakegmail.com,407562,407562,Silver
sarah_lewis@fakegmail.com,824644,164929,Silver
luke_barnes@gameofthron.es,160328,160328,Silver
emily_ellis@fakegmail.com,469838,117460,Silver
victor_patel@fakegmail.com,867965,867965,Silver
karina_martin@fakegmail.com,112758,28190,Silver
robert_jordan@fakegmail.com,128847,42949,Silver
roger_ashton-griffiths@gameofthron.es,271252,135626,Silver
ronald_cox@fakegmail.com,311671,311671,Silver
paul_kaye@gameofthron.es,454847,227424,Silver
faye_marsay@gameofthron.es,22891,4578,Silver
brenock_o'connor@gameofthron.es,801111,801111,Silver
michael_condron@gameofthron.es,439425,109856,Silver
richard_davis@fakegmail.com,915945,915945,Silver
lisa_rasmussen@fakegmail.com,34923,11641,Silver
cameron_duran@fakegmail.com,857339,171468,Silver
connie_johnson@fakegmail.com,370285,123428,Silver
victor_fleming@fakegmail.com,54277,13569,Silver
brandon_hardy@fakegmail.com,97445,24361,Silver
kathryn_sosa@fakegmail.com,754069,251356,Silver
mrs._ariana_nunez@fakegmail.com,623715,311858,Silver
megan_richards@fakegmail.com,964334,192867,Silver
yvette_roth@fakegmail.com,270710,90237,Silver
kelsey_smith@fakegmail.com,249892,249892,Silver
keith_phillips@fakegmail.com,395806,131935,Silver
morgan_smith@fakegmail.com,66282,66282,Silver
jason_smith@fakegmail.com,934336,186867,Silver
megan_turner@fakegmail.com,500910,125228,Silver
amy_phillips@fakegmail.com,787274,787274,Silver
garrett_obrien@fakegmail.com,38211,38211,Silver
lori_franklin@fakegmail.com,989731,329910,Silver
daniel_simmons@fakegmail.com,208109,104055,Silver
kenneth_chandler@fakegmail.com,48025,48025,Silver
paula_sullivan@fakegmail.com,872563,290854,Silver
brenda_martin@fakegmail.com,724785,241595,Silver
javier_smith@fakegmail.com,951895,317298,Silver
anthony_thompson@fakegmail.com,189915,47479,Silver
joshua_kent@fakegmail.com,882747,882747,Silver
thomas_buckley@fakegmail.com,420065,140022,Silver
richard_schmidt@fakegmail.com,53736,13434,Silver
anthony_smith@fakegmail.com,894242,298081,Silver
michael_day@fakegmail.com,454053,90811,Silver
mercedes_tyler@fakegmail.com,250400,250400,Silver
kristen_schmidt@fakegmail.com,848357,169671,Silver
john_roman@fakegmail.com,787724,157545,Silver
justin_williams@fakegmail.com,218323,43665,Silver
april_cole@fakegmail.com,836859,167372,Silver
kimberly_gates@fakegmail.com,402820,201410,Silver
andrea_le@fakegmail.com,609108,609108,Silver
patricia_good@fakegmail.com,122754,30689,Silver
barbara_gonzalez@fakegmail.com,44221,8844,Silver
denise_bryant@fakegmail.com,871607,217902,Silver
victoria_sanders@fakegmail.com,664957,166239,Silver
taylor_scott@fakegmail.com,644595,128919,Silver
taylor_hill@fakegmail.com,405497,202749,Silver
melissa_jones@fakegmail.com,11417,2854,Silver
amy_ramirez@fakegmail.com,125842,41947,Silver
christopher_robinson@fakegmail.com,32960,8240,Silver
phillip_collins@fakegmail.com,603906,120781,Silver
edward_barrett@fakegmail.com,602701,602701,Silver
lisa_russo@fakegmail.com,937347,234337,Silver
thomas_morris@fakegmail.com,261675,65419,Silver
ms._cathy_miller@fakegmail.com,823506,274502,Silver
elizabeth_wiggins@fakegmail.com,299691,59938,Silver
lisa_silva@fakegmail.com,585507,117101,Silver
nicholas_webster@fakegmail.com,328813,82203,Silver
teresa_thomas@fakegmail.com,555871,185290,Silver
catherine_romero@fakegmail.com,521251,173750,Silver
michael_moore@fakegmail.com,264405,132203,Silver
christian_williams@fakegmail.com,717067,239022,Silver
jason_hernandez@fakegmail.com,236401,118201,Silver
denise_davidson@fakegmail.com,917670,917670,Silver
julia_nichols@fakegmail.com,564357,282179,Silver
heather_leonard@fakegmail.com,417756,208878,Silver
melissa_young@fakegmail.com,382306,191153,Silver
john_rice@fakegmail.com,92771,46386,Silver
blake_sellers@fakegmail.com,98598,49299,Silver
theresa_holmes@fakegmail.com,953901,476951,Silver
bradley_brooks@fakegmail.com,862238,431119,Silver
thomas_green@fakegmail.com,945350,945350,Silver
jonathon_mccullough@fakegmail.com,632841,126568,Silver
jerry_cabrera@fakegmail.com,998842,332947,Silver
jamie_santana@fakegmail.com,15383,3077,Silver
mary_mitchell@fakegmail.com,757125,252375,Silver
lori_blankenship@fakegmail.com,393159,98290,Silver
deborah_kennedy@fakegmail.com,708578,141716,Silver
paul_bailey@fakegmail.com,81747,27249,Silver
john_bishop@fakegmail.com,87902,87902,Silver
yolanda_owen@fakegmail.com,209542,52386,Silver
nichole_miller@fakegmail.com,61299,61299,Silver
nicholas_johnson@fakegmail.com,708229,236076,Silver
desiree_pierce@fakegmail.com,447206,111802,Silver
connie_barton@fakegmail.com,934306,311435,Silver
anthony_cline@fakegmail.com,421413,84283,Silver
donna_russell@fakegmail.com,852408,426204,Silver
blake_fitzgerald@fakegmail.com,115132,38377,Silver
shawn_mccormick@fakegmail.com,225350,112675,Silver
anthony_hurst@fakegmail.com,664729,664729,Silver
patrick_knight@fakegmail.com,287900,143950,Silver
ashlee_hart@fakegmail.com,137174,27435,Silver
magicz@cats.com,54179,54179,Silver
foobaz@bar.com,147268,147268,Silver
eric_navarro@fakegmail.com,958557,191711,Silver
donna_smith@fakegmail.com,245313,81771,Silver
jose_hall@fakegmail.com,878644,292881,Silver
jeffrey_roberts@fakegmail.com,496826,124207,Silver
jordan_medina@fakegmail.com,695384,347692,Silver
jennifer_frazier@fakegmail.com,335727,111909,Silver
1 email points_total points_wallet tier
2 aidan_gillen@gameofthron.es 371118 92780 Gold
3 harry_lloyd@gameofthron.es 243542 81181 Silver
4 michelle_fairley@gameofthron.es 301074 301074 Silver
5 kit_harington@gameofthron.es 840961 210240 Silver
6 sophie_turner@gameofthron.es 896887 298962 Silver
7 maisie_williams@gameofthron.es 232576 116288 Silver
8 richard_madden@gameofthron.es 888334 888334 Silver
9 alfie_allen@gameofthron.es 328439 65688 Gold
10 isaac_hempstead_wright@gameofthron.es 55755 11151 Silver
11 mark_addy@gameofthron.es 760455 380228 Silver
12 rory_mccann@gameofthron.es 921802 921802 Silver
13 sean_bean@gameofthron.es 121698 121698 Silver
14 jack_gleeson@gameofthron.es 522857 174286 Silver
15 nikolaj_coster-waldau@gameofthron.es 311769 311769 Silver
16 iain_glen@gameofthron.es 892838 446419 Silver
17 jason_momoa@gameofthron.es 886541 295514 Silver
18 lena_headey@gameofthron.es 376561 125520 Silver
19 peter_dinklage@gameofthron.es 604113 302057 Silver
20 jerome_flynn@gameofthron.es 130830 43610 Silver
21 emilia_clarke@gameofthron.es 212897 212897 Silver
22 conleth_hill@gameofthron.es 382143 382143 Silver
23 sibel_kekilli@gameofthron.es 183257 36651 Silver
24 charles_dance@gameofthron.es 237769 59442 Silver
25 james_cosmo@gameofthron.es 483039 483039 Silver
26 rose_leslie@gameofthron.es 268091 268091 Silver
27 joe_dempsie@gameofthron.es 756231 252077 Silver
28 kristofer_hivju@gameofthron.es 218877 43775 Silver
29 oona_chaplin@gameofthron.es 981827 327276 Silver
30 natalie_dormer@gameofthron.es 101141 33714 Silver
31 hannah_murray@gameofthron.es 278877 278877 Silver
32 gwendoline_christie@gameofthron.es 47643 11911 Silver
33 iwan_rheon@gameofthron.es 10021 5011 Silver
34 michiel_huisman@gameofthron.es 748972 149794 Silver
35 indira_varma@gameofthron.es 453672 113418 Silver
36 liam_cunningham@gameofthron.es 7458 3729 Silver
37 john_bradley-west@gameofthron.es 268615 67154 Silver
38 nathalie_emmanuel@gameofthron.es 581997 145499 Silver
39 stephen_dillane@gameofthron.es 963996 963996 Silver
40 dean-charles_chapman@gameofthron.es 428911 214456 Silver
41 jonathan_pryce@gameofthron.es 315519 105173 Silver
42 natalia_tena@gameofthron.es 368297 92074 Silver
43 carice_van_houten@gameofthron.es 829341 207335 Silver
44 mark_stanley@gameofthron.es 37041 7408 Silver
45 art_parkinson@gameofthron.es 784606 392303 Silver
46 esme_bianco@gameofthron.es 447069 223535 Silver
47 hafthór_júlíus_björnsson@gameofthron.es 498905 124726 Silver
48 dominic_carter@gameofthron.es 734054 734054 Silver
49 kristian_nairn@gameofthron.es 979762 244941 Silver
50 nell_tiger_free@gameofthron.es 554970 138743 Silver
51 donald_sumpter@gameofthron.es 306128 61226 Silver
52 ron_donachie@gameofthron.es 691770 230590 Silver
53 eugene_simon@gameofthron.es 903412 903412 Silver
54 amrita_acharia@gameofthron.es 331518 110506 Silver
55 ian_mcelhinney@gameofthron.es 428641 428641 Silver
56 ian_gelder@gameofthron.es 880463 220116 Silver
57 roxanne_mckee@gameofthron.es 913367 913367 Silver
58 tom_wlaschiha@gameofthron.es 806067 161213 Silver
59 michael_mcelhatton@gameofthron.es 712946 237649 Silver
60 julian_glover@gameofthron.es 729666 364833 Silver
61 ian_beattie@gameofthron.es 829971 414986 Silver
62 finn_jones@gameofthron.es 41975 8395 Silver
63 ben_hawkey@gameofthron.es 919040 229760 Silver
64 richard_dormer@gameofthron.es 760838 380419 Silver
65 brian_fortune@gameofthron.es 227457 75819 Silver
66 daniel_portman@gameofthron.es 860359 286786 Silver
67 gemma_whelan@gameofthron.es 576875 144219 Silver
68 ben_crompton@gameofthron.es 138273 46091 Silver
69 tara_fitzgerald@gameofthron.es 715873 143175 Silver
70 jacob_anderson@gameofthron.es 310174 310174 Silver
71 anton_lesser@gameofthron.es 742440 247480 Silver
72 diana_rigg@gameofthron.es 371490 185745 Silver
73 kerry_ingram@gameofthron.es 391027 97757 Silver
74 ellie_kendrick@gameofthron.es 78367 15673 Silver
75 peter_vaughan@gameofthron.es 604767 604767 Silver
76 josef_altin@gameofthron.es 243760 121880 Silver
77 owen_teale@gameofthron.es 88378 17676 Silver
78 thomas_brodie-sangster@gameofthron.es 532844 266422 Silver
79 greg_powell@fakegmail.com 407562 407562 Silver
80 sarah_lewis@fakegmail.com 824644 164929 Silver
81 luke_barnes@gameofthron.es 160328 160328 Silver
82 emily_ellis@fakegmail.com 469838 117460 Silver
83 victor_patel@fakegmail.com 867965 867965 Silver
84 karina_martin@fakegmail.com 112758 28190 Silver
85 robert_jordan@fakegmail.com 128847 42949 Silver
86 roger_ashton-griffiths@gameofthron.es 271252 135626 Silver
87 ronald_cox@fakegmail.com 311671 311671 Silver
88 paul_kaye@gameofthron.es 454847 227424 Silver
89 faye_marsay@gameofthron.es 22891 4578 Silver
90 brenock_o'connor@gameofthron.es 801111 801111 Silver
91 michael_condron@gameofthron.es 439425 109856 Silver
92 richard_davis@fakegmail.com 915945 915945 Silver
93 lisa_rasmussen@fakegmail.com 34923 11641 Silver
94 cameron_duran@fakegmail.com 857339 171468 Silver
95 connie_johnson@fakegmail.com 370285 123428 Silver
96 victor_fleming@fakegmail.com 54277 13569 Silver
97 brandon_hardy@fakegmail.com 97445 24361 Silver
98 kathryn_sosa@fakegmail.com 754069 251356 Silver
99 mrs._ariana_nunez@fakegmail.com 623715 311858 Silver
100 megan_richards@fakegmail.com 964334 192867 Silver
101 yvette_roth@fakegmail.com 270710 90237 Silver
102 kelsey_smith@fakegmail.com 249892 249892 Silver
103 keith_phillips@fakegmail.com 395806 131935 Silver
104 morgan_smith@fakegmail.com 66282 66282 Silver
105 jason_smith@fakegmail.com 934336 186867 Silver
106 megan_turner@fakegmail.com 500910 125228 Silver
107 amy_phillips@fakegmail.com 787274 787274 Silver
108 garrett_obrien@fakegmail.com 38211 38211 Silver
109 lori_franklin@fakegmail.com 989731 329910 Silver
110 daniel_simmons@fakegmail.com 208109 104055 Silver
111 kenneth_chandler@fakegmail.com 48025 48025 Silver
112 paula_sullivan@fakegmail.com 872563 290854 Silver
113 brenda_martin@fakegmail.com 724785 241595 Silver
114 javier_smith@fakegmail.com 951895 317298 Silver
115 anthony_thompson@fakegmail.com 189915 47479 Silver
116 joshua_kent@fakegmail.com 882747 882747 Silver
117 thomas_buckley@fakegmail.com 420065 140022 Silver
118 richard_schmidt@fakegmail.com 53736 13434 Silver
119 anthony_smith@fakegmail.com 894242 298081 Silver
120 michael_day@fakegmail.com 454053 90811 Silver
121 mercedes_tyler@fakegmail.com 250400 250400 Silver
122 kristen_schmidt@fakegmail.com 848357 169671 Silver
123 john_roman@fakegmail.com 787724 157545 Silver
124 justin_williams@fakegmail.com 218323 43665 Silver
125 april_cole@fakegmail.com 836859 167372 Silver
126 kimberly_gates@fakegmail.com 402820 201410 Silver
127 andrea_le@fakegmail.com 609108 609108 Silver
128 patricia_good@fakegmail.com 122754 30689 Silver
129 barbara_gonzalez@fakegmail.com 44221 8844 Silver
130 denise_bryant@fakegmail.com 871607 217902 Silver
131 victoria_sanders@fakegmail.com 664957 166239 Silver
132 taylor_scott@fakegmail.com 644595 128919 Silver
133 taylor_hill@fakegmail.com 405497 202749 Silver
134 melissa_jones@fakegmail.com 11417 2854 Silver
135 amy_ramirez@fakegmail.com 125842 41947 Silver
136 christopher_robinson@fakegmail.com 32960 8240 Silver
137 phillip_collins@fakegmail.com 603906 120781 Silver
138 edward_barrett@fakegmail.com 602701 602701 Silver
139 lisa_russo@fakegmail.com 937347 234337 Silver
140 thomas_morris@fakegmail.com 261675 65419 Silver
141 ms._cathy_miller@fakegmail.com 823506 274502 Silver
142 elizabeth_wiggins@fakegmail.com 299691 59938 Silver
143 lisa_silva@fakegmail.com 585507 117101 Silver
144 nicholas_webster@fakegmail.com 328813 82203 Silver
145 teresa_thomas@fakegmail.com 555871 185290 Silver
146 catherine_romero@fakegmail.com 521251 173750 Silver
147 michael_moore@fakegmail.com 264405 132203 Silver
148 christian_williams@fakegmail.com 717067 239022 Silver
149 jason_hernandez@fakegmail.com 236401 118201 Silver
150 denise_davidson@fakegmail.com 917670 917670 Silver
151 julia_nichols@fakegmail.com 564357 282179 Silver
152 heather_leonard@fakegmail.com 417756 208878 Silver
153 melissa_young@fakegmail.com 382306 191153 Silver
154 john_rice@fakegmail.com 92771 46386 Silver
155 blake_sellers@fakegmail.com 98598 49299 Silver
156 theresa_holmes@fakegmail.com 953901 476951 Silver
157 bradley_brooks@fakegmail.com 862238 431119 Silver
158 thomas_green@fakegmail.com 945350 945350 Silver
159 jonathon_mccullough@fakegmail.com 632841 126568 Silver
160 jerry_cabrera@fakegmail.com 998842 332947 Silver
161 jamie_santana@fakegmail.com 15383 3077 Silver
162 mary_mitchell@fakegmail.com 757125 252375 Silver
163 lori_blankenship@fakegmail.com 393159 98290 Silver
164 deborah_kennedy@fakegmail.com 708578 141716 Silver
165 paul_bailey@fakegmail.com 81747 27249 Silver
166 john_bishop@fakegmail.com 87902 87902 Silver
167 yolanda_owen@fakegmail.com 209542 52386 Silver
168 nichole_miller@fakegmail.com 61299 61299 Silver
169 nicholas_johnson@fakegmail.com 708229 236076 Silver
170 desiree_pierce@fakegmail.com 447206 111802 Silver
171 connie_barton@fakegmail.com 934306 311435 Silver
172 anthony_cline@fakegmail.com 421413 84283 Silver
173 donna_russell@fakegmail.com 852408 426204 Silver
174 blake_fitzgerald@fakegmail.com 115132 38377 Silver
175 shawn_mccormick@fakegmail.com 225350 112675 Silver
176 anthony_hurst@fakegmail.com 664729 664729 Silver
177 patrick_knight@fakegmail.com 287900 143950 Silver
178 ashlee_hart@fakegmail.com 137174 27435 Silver
179 magicz@cats.com 54179 54179 Silver
180 foobaz@bar.com 147268 147268 Silver
181 eric_navarro@fakegmail.com 958557 191711 Silver
182 donna_smith@fakegmail.com 245313 81771 Silver
183 jose_hall@fakegmail.com 878644 292881 Silver
184 jeffrey_roberts@fakegmail.com 496826 124207 Silver
185 jordan_medina@fakegmail.com 695384 347692 Silver
186 jennifer_frazier@fakegmail.com 335727 111909 Silver

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"_id":{"$oid":"5a97f9c91c807bb9c6eb5fb4"},"user_id":"t3qulfeem@kwiv5.6ur","jwt":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1MTk5MDkzMjEsIm5iZiI6MTUxOTkwOTMyMSwianRpIjoiNmJlZDAwMWYtNTFiYi00NzVhLTgxZDAtMDcwNGE5Mjk0MWZlIiwiZXhwIjoxNTE5OTEwMjIxLCJpZGVudGl0eSI6eyJlbWFpbCI6InQzcXVsZmVlbUBrd2l2NS42dXIiLCJuYW1lIjoiM2lveHJtZnF4IiwicGFzc3dvcmQiOm51bGx9LCJmcmVzaCI6ZmFsc2UsInR5cGUiOiJhY2Nlc3MiLCJ1c2VyX2NsYWltcyI6eyJ1c2VyIjp7ImVtYWlsIjoidDNxdWxmZWVtQGt3aXY1LjZ1ciIsIm5hbWUiOiIzaW94cm1mcXgiLCJwYXNzd29yZCI6bnVsbH19fQ.ejtr_NyZyBronWMKuE0RFTjWej--T0zGrdc_iymGtVs"}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,185 @@
{"_id":{"$oid":"59b99db4cfa9a34dcd7885b6"},"name":"Ned Stark","email":"sean_bean@gameofthron.es","password":"$2b$12$UREFwsRUoyF0CRqGNK0LzO0HM/jLhgUCNNIJ9RJAqMUQ74crlJ1Vu"}
{"_id":{"$oid":"59b99db4cfa9a34dcd7885b7"},"name":"Robert Baratheon","email":"mark_addy@gameofthron.es","password":"$2b$12$yGqxLG9LZpXA2xVDhuPnSOZd.VURVkz7wgOLY3pnO0s7u2S1ZO32y"}
{"_id":{"$oid":"59b99db5cfa9a34dcd7885b8"},"name":"Jaime Lannister","email":"nikolaj_coster-waldau@gameofthron.es","password":"$2b$12$6vz7wiwO.EI5Rilvq1zUc./9480gb1uPtXcahDxIadgyC3PS8XCUK"}
{"_id":{"$oid":"59b99db5cfa9a34dcd7885b9"},"name":"Catelyn Stark","email":"michelle_fairley@gameofthron.es","password":"$2b$12$fiaTH5Sh1zKNFX2i/FTEreWGjxoJxvmV7XL.qlfqCr8CwOxK.mZWS"}
{"_id":{"$oid":"59b99db6cfa9a34dcd7885ba"},"name":"Cersei Lannister","email":"lena_headey@gameofthron.es","password":"$2b$12$FExjgr7CLhNCa.oUsB9seub8mqcHzkJCFZ8heMc8CeIKOZfeTKP8m"}
{"_id":{"$oid":"59b99db6cfa9a34dcd7885bb"},"name":"Daenerys Targaryen","email":"emilia_clarke@gameofthron.es","password":"$2b$12$NzpbWHdMytemLtTfFKduHenr2NZ.rvxIKuYM4AWLTFaUShxbJ.G3q"}
{"_id":{"$oid":"59b99db6cfa9a34dcd7885bc"},"name":"Jorah Mormont","email":"iain_glen@gameofthron.es","password":"$2b$12$K8bKkwnpkrjsBPzASZxO/.yj7d9kvupiVtO6JA3Xl106AKXr3pXFK"}
{"_id":{"$oid":"59b99db7cfa9a34dcd7885bd"},"name":"Petyr Baelish","email":"aidan_gillen@gameofthron.es","password":"$2b$12$qM.YvmiekyYYY7p7phpK3OicbRCDkN7ESwYAnG/o9YnfHC0Mhkmbi"}
{"_id":{"$oid":"59b99db8cfa9a34dcd7885be"},"name":"Viserys Targaryen","email":"harry_lloyd@gameofthron.es","password":"$2b$12$cpwVmU4DyuQxgwpdrVJhaudzbKOXlHRbf.tpCuHjpAqonuoyvvEG6"}
{"_id":{"$oid":"59b99db9cfa9a34dcd7885bf"},"name":"Jon Snow","email":"kit_harington@gameofthron.es","password":"$2b$12$fDEu1Ru66tLWAVidMN.b0.929BlfnyqdGuhWMyzfOAf/ATYOyLoY6"}
{"_id":{"$oid":"59b99db9cfa9a34dcd7885c0"},"name":"Sansa Stark","email":"sophie_turner@gameofthron.es","password":"$2b$12$nCIVE81..AtAoysPZkl19.G5V0EdIwwsZh1f18lxWEr3dlpG/Uusi"}
{"_id":{"$oid":"59b99dbacfa9a34dcd7885c1"},"name":"Arya Stark","email":"maisie_williams@gameofthron.es","password":"$2b$12$19h3KjeTg3/sPNFHztdb6eGWKrCxIwlVXVSh9POSi5PS9kSlguZEq"}
{"_id":{"$oid":"59b99dbacfa9a34dcd7885c2"},"name":"Robb Stark","email":"richard_madden@gameofthron.es","password":"$2b$12$XPLvWQW7tjWc/PX9jMVRnO8w.lR6hv144ee8pc8nDsWIAWxfwxHzy"}
{"_id":{"$oid":"59b99dbbcfa9a34dcd7885c3"},"name":"Theon Greyjoy","email":"alfie_allen@gameofthron.es","password":"$2b$12$x574mziridS3mEQVTbKbY.lK.ngIDyZJnTw17G7Gk6n4lnWVSrWL."}
{"_id":{"$oid":"59b99dbbcfa9a34dcd7885c4"},"name":"Bran Stark","email":"isaac_hempstead_wright@gameofthron.es","password":"$2b$12$Z7/ztVm8eWMDwTg.doS.UO7JbsbA9IbLomND1VxIZEdAN3keW6csS"}
{"_id":{"$oid":"59b99dbbcfa9a34dcd7885c5"},"name":"Joffrey Baratheon","email":"jack_gleeson@gameofthron.es","password":"$2b$12$fIYLjRg5tZcTcqy30.MJLO4JRblLhsIhFwYTgUpFBbvnf9S4ONbtW"}
{"_id":{"$oid":"59b99dbccfa9a34dcd7885c6"},"name":"Sandor Clegane","email":"rory_mccann@gameofthron.es","password":"$2b$12$DKIKOBMbN76vskkRyJ1AjuELigfnx.SeG8vu73k24kfMcO637bSqa"}
{"_id":{"$oid":"59b99dbdcfa9a34dcd7885c7"},"name":"Tyrion Lannister","email":"peter_dinklage@gameofthron.es","password":"$2b$12$xtHwQNXYlQzP2REobUDlzuQimjzBlXrTx1GnwP.xkfULeuuUpRxa2"}
{"_id":{"$oid":"59b99dbdcfa9a34dcd7885c8"},"name":"Khal Drogo","email":"jason_momoa@gameofthron.es","password":"$2b$12$7tgpVkBxUqQiYFkHjZyoMuEzFU5BSI.FYkOXHu4zCRlRsa15sHQo6"}
{"_id":{"$oid":"59b99dbecfa9a34dcd7885c9"},"name":"Davos Seaworth","email":"liam_cunningham@gameofthron.es","password":"$2b$12$jbgNoWG97LHNIm4axwXDz.tkFITsmw/aylIY/lZDaJRgnHZjB029e"}
{"_id":{"$oid":"59b99dbecfa9a34dcd7885ca"},"name":"Samwell Tarly","email":"john_bradley-west@gameofthron.es","password":"$2b$12$ZcZj9wKjlT/dCCrmupiZZ..JA3c9HoufxRygL1DkY9hsClT0iyflG"}
{"_id":{"$oid":"59b99dbecfa9a34dcd7885cb"},"name":"Margaery Tyrell","email":"natalie_dormer@gameofthron.es","password":"$2b$12$AjC.876rd2dgsSIu.5c4qembdVfdDajMIgueMYuOBoskJUGHzpw46"}
{"_id":{"$oid":"59b99dbfcfa9a34dcd7885cc"},"name":"Stannis Baratheon","email":"stephen_dillane@gameofthron.es","password":"$2b$12$vbPwOM9QkSOsOXRgLSZiqe9JPJtBX1JUwm06d3lYVViKxrYCIyhEm"}
{"_id":{"$oid":"59b99dbfcfa9a34dcd7885cd"},"name":"Melisandre","email":"carice_van_houten@gameofthron.es","password":"$2b$12$ZdSvCDMwVLFgJGDOsDbFLOD/utICnkbJV0OVJJ8lUHqSK3VbuqKuS"}
{"_id":{"$oid":"59b99dbfcfa9a34dcd7885ce"},"name":"Jeor Mormont","email":"james_cosmo@gameofthron.es","password":"$2b$12$tz5dSvAjtduFuuXFQwMH2OJwb3QKr9/gR5uefaQ3gHJojhLaKxdNK"}
{"_id":{"$oid":"59b99dc0cfa9a34dcd7885cf"},"name":"Bronn","email":"jerome_flynn@gameofthron.es","password":"$2b$12$9rzMIF3lv7kASdTdam2eOOjWrDSN.qi2hpY5tyOfDPe545XfrQHpu"}
{"_id":{"$oid":"59b99dc0cfa9a34dcd7885d0"},"name":"Varys","email":"conleth_hill@gameofthron.es","password":"$2b$12$mV9NHXHLISu3fDdd6jtU2.6DstBgnC6iWQQR.1h/MsDZp3ftTUBSq"}
{"_id":{"$oid":"59b99dc0cfa9a34dcd7885d1"},"name":"Shae","email":"sibel_kekilli@gameofthron.es","password":"$2b$12$FyKikoJynO1kGJ6cTuXaKeKRWauwI5TNlTYiNBgPnizN6XoGB8qpi"}
{"_id":{"$oid":"59b99dc2cfa9a34dcd7885d2"},"name":"Tywin Lannister","email":"charles_dance@gameofthron.es","password":"$2b$12$/i04T5yEJvmsBhF0Jd.kJOk3ZhRzezbTU7ASEM5o43Xxsa4o6IgEy"}
{"_id":{"$oid":"59b99dc2cfa9a34dcd7885d3"},"name":"Ygritte","email":"rose_leslie@gameofthron.es","password":"$2b$12$knwl2v71.oOhFA1W.Yenle8kil56LqhWCOvM7/JVy8E5YrOoZisUi"}
{"_id":{"$oid":"59b99dc2cfa9a34dcd7885d4"},"name":"Talisa Maegyr","email":"oona_chaplin@gameofthron.es","password":"$2b$12$B3DKrkTVNJDlgToXClpcwOJvnKICUsLcrTxNfZIeoqbHIQURsNrXS"}
{"_id":{"$oid":"59b99dc3cfa9a34dcd7885d5"},"name":"Gendry","email":"joe_dempsie@gameofthron.es","password":"$2b$12$ctQymjuvXC5dQXYTWX695eJ/0IEXLfXhNiuzad0bL7j8n9YCBq92K"}
{"_id":{"$oid":"59b99dc3cfa9a34dcd7885d6"},"name":"Tormund Giantsbane","email":"kristofer_hivju@gameofthron.es","password":"$2b$12$SsfE7EbmV/HH6nii2jJFOe59P91dAV6CqYdGUDOTkNwcPAScUJyVa"}
{"_id":{"$oid":"59b99dc5cfa9a34dcd7885d7"},"name":"Gilly","email":"hannah_murray@gameofthron.es","password":"$2b$12$s6/CDf3HFLl3sYNVdOs8sOvdR7HOeQln/ByVQwDGRyTOH5S6qlI7m"}
{"_id":{"$oid":"59b99dc5cfa9a34dcd7885d8"},"name":"Brienne of Tarth","email":"gwendoline_christie@gameofthron.es","password":"$2b$12$YjMZPFrj1qS6I/Zy1bxlgOV402ijFcNE.6YVueL5FoWK3eE/QVgKu"}
{"_id":{"$oid":"59b99dc5cfa9a34dcd7885d9"},"name":"Ramsay Bolton","email":"iwan_rheon@gameofthron.es","password":"$2b$12$a5CtSXflNAlkWDVmC70vN.06Zds9s3VlnvSVLNM4quXNkF5spOCsa"}
{"_id":{"$oid":"59b99dc6cfa9a34dcd7885da"},"name":"Ellaria Sand","email":"indira_varma@gameofthron.es","password":"$2b$12$/sfLmn9AwehR9itBml.p..fKYxUv66om0TallTLMjw2klrmiLwaHy"}
{"_id":{"$oid":"59b99dc6cfa9a34dcd7885db"},"name":"Daario Naharis","email":"michiel_huisman@gameofthron.es","password":"$2b$12$22Oqs3Wq.ObJ3Vr68TJKteCSEV1JWIt8jM7/3lf21vOA.jQkdHoBq"}
{"_id":{"$oid":"59b99dc7cfa9a34dcd7885dc"},"name":"Missandei","email":"nathalie_emmanuel@gameofthron.es","password":"$2b$12$wMY9mXJCiDZ5dPbgroygBOKjWbuCzv.Snb1sZlp7v41LzyueP/G.S"}
{"_id":{"$oid":"59b99dc7cfa9a34dcd7885dd"},"name":"Jaqen H'ghar","email":"tom_wlaschiha@gameofthron.es","password":"$2b$12$sgxhWIzY6UiWvWFRMslCDusielBdf8tpNHraxHAS3c9QNwcCHdHJq"}
{"_id":{"$oid":"59b99dc8cfa9a34dcd7885de"},"name":"Tommen Baratheon","email":"dean-charles_chapman@gameofthron.es","password":"$2b$12$POxM5GGAYJNe2phLqcZJ5.3MXEVhUXTQouqvc3hwCU1ZItYbySQsy"}
{"_id":{"$oid":"59b99dc9cfa9a34dcd7885df"},"name":"Roose Bolton","email":"michael_mcelhatton@gameofthron.es","password":"$2b$12$JWXzYGip0vvuT40B23mZB.KKoHocgoW2FshxzmhDstZqR23vEtZpS"}
{"_id":{"$oid":"59b99dcacfa9a34dcd7885e0"},"name":"The High Sparrow","email":"jonathan_pryce@gameofthron.es","password":"$2b$12$wWkC3fCEuI5X1WoXJft0hOu2qm95MKVmI996/68kXBRUn0HXHebHC"}
{"_id":{"$oid":"59b99dcacfa9a34dcd7885e1"},"name":"Grand Maester Pycelle","email":"julian_glover@gameofthron.es","password":"$2b$12$R2KQQQMmjcrbm5XgGdkFJ.38e0I7KptV479H2p1UJ2t5TTb3OSww6"}
{"_id":{"$oid":"59b99dcacfa9a34dcd7885e2"},"name":"Meryn Trant","email":"ian_beattie@gameofthron.es","password":"$2b$12$rB95MlNcAdrflKD1gUdiTOg55dbPUtH6po4kKMHGxQjbU9L4k0LBu"}
{"_id":{"$oid":"59b99dcbcfa9a34dcd7885e3"},"name":"Hodor","email":"kristian_nairn@gameofthron.es","password":"$2b$12$hFkSycBpMDENs/sT.5y0feifE5IluHUJmYHqH/lSkcc81/HRzzRSq"}
{"_id":{"$oid":"59b99dcbcfa9a34dcd7885e4"},"name":"Grenn","email":"mark_stanley@gameofthron.es","password":"$2b$12$gpgDQ2RBHotU4x/ppd0P9ueseDdLTzFHB.4kjkez/ZNerubyFSy1i"}
{"_id":{"$oid":"59b99dcccfa9a34dcd7885e5"},"name":"Osha","email":"natalia_tena@gameofthron.es","password":"$2b$12$NpElja7NerH/Vz.6pN0vV.7PNo1fOvMgFx0O8VOro6idM4Evn7n4G"}
{"_id":{"$oid":"59b99dcccfa9a34dcd7885e6"},"name":"Rickon Stark","email":"art_parkinson@gameofthron.es","password":"$2b$12$LKBf/wrMe29RwjUCkm6sq.AfuAXshbX6Evys3twd9vaGEsEm6YBqC"}
{"_id":{"$oid":"59b99dcdcfa9a34dcd7885e7"},"name":"Ros","email":"esme_bianco@gameofthron.es","password":"$2b$12$dpUAAVPghWXEu0pg0Kv9rOP9bZexMblG911BJzJD/2HOuMat6ZsOe"}
{"_id":{"$oid":"59b99dcdcfa9a34dcd7885e8"},"name":"Gregor Clegane","email":"hafthór_júlíus_björnsson@gameofthron.es","password":"$2b$12$6NQKRPtpvs.3w2VuLBgQv.nYBplKlGVK3GRvLqw1n06wO424E.zq6"}
{"_id":{"$oid":"59b99dcecfa9a34dcd7885e9"},"name":"Janos Slynt","email":"dominic_carter@gameofthron.es","password":"$2b$12$ssMaPHBLj9tGpLgRXWSCeODrtccHwVbZvDKckjSg1duBLsBZOco8e"}
{"_id":{"$oid":"59b99dcecfa9a34dcd7885ea"},"name":"Lancel Lannister","email":"eugene_simon@gameofthron.es","password":"$2b$12$mNWiHoOqOWQser3s6ezqZeTU5vhskTq.K7xkeTA2P.CIfoWsHvonO"}
{"_id":{"$oid":"59b99dcecfa9a34dcd7885eb"},"name":"Myrcella Baratheon","email":"nell_tiger_free@gameofthron.es","password":"$2b$12$boJbPqaRG45hQs7jzcwLWu03lGXG9DHIn3rVHcJQ/NK0PaYokP5eu"}
{"_id":{"$oid":"59b99dcfcfa9a34dcd7885ec"},"name":"Rodrik Cassel","email":"ron_donachie@gameofthron.es","password":"$2b$12$dIvO2KpkHkje98eMZg.exuDR.MeOkHlRC9R7PTKj1D66PhX4NaDP6"}
{"_id":{"$oid":"59b99dcfcfa9a34dcd7885ed"},"name":"Maester Luwin","email":"donald_sumpter@gameofthron.es","password":"$2b$12$K9m5hh0Lh.NtYqRpxF40NeWTRwOM7nPp4NJL5v/9fZZ/vpIWKN3KO"}
{"_id":{"$oid":"59b99dcfcfa9a34dcd7885ee"},"name":"Irri","email":"amrita_acharia@gameofthron.es","password":"$2b$12$mTvd3eFqgflqO74rS95zKOFU3wKRe5alg.iM23AknNnpZ/TdT95eK"}
{"_id":{"$oid":"59b99dd0cfa9a34dcd7885ef"},"name":"Doreah","email":"roxanne_mckee@gameofthron.es","password":"$2b$12$3M34QX9A/7jNLn9neSddUeW5oJfcl5OYOqYUL.7L87/ThA8Xbfug6"}
{"_id":{"$oid":"59b99dd0cfa9a34dcd7885f0"},"name":"Kevan Lannister","email":"ian_gelder@gameofthron.es","password":"$2b$12$YB/GLht749jn9jxcwOnw4.ZekNoiSzmS8qS.raqFzZPrNbBJAB20O"}
{"_id":{"$oid":"59b99dd1cfa9a34dcd7885f1"},"name":"Barristan Selmy","email":"ian_mcelhinney@gameofthron.es","password":"$2b$12$IabcnI3C6lUTfq2Ez5f0bOEsM6Hok6JsPMyTxnVHwZGIEaHtpohsy"}
{"_id":{"$oid":"59b99dd6cfa9a34dcd7885f2"},"name":"Rast","email":"luke_barnes@gameofthron.es","password":"$2b$12$wzKOV4fkmI5hfiQLFYpSDePsSBqenWs8CpI1N7OcD1A.3NF98adqy"}
{"_id":{"$oid":"59b99dd6cfa9a34dcd7885f3"},"name":"Maester Aemon","email":"peter_vaughan@gameofthron.es","password":"$2b$12$uOefAK8L28vlzZ9lsZV2Q.LplAND.FPwKHPmZ7wgXeO/F0mbVR1b2"}
{"_id":{"$oid":"59b99dd6cfa9a34dcd7885f4"},"name":"Pypar","email":"josef_altin@gameofthron.es","password":"$2b$12$GTKOrQ2gHc1o0OE37ub6d.yKxI4o9RU/72kPAbiaUbqkrANKYO34W"}
{"_id":{"$oid":"59b99dd7cfa9a34dcd7885f5"},"name":"Alliser Thorne","email":"owen_teale@gameofthron.es","password":"$2b$12$IWJV4xTZ4dyBsvwQQ2FlF.yw3Mfy.XZCOsprt6kaLRtHu9k6ZHbx."}
{"_id":{"$oid":"59b99dd7cfa9a34dcd7885f6"},"name":"Othell Yarwyck","email":"brian_fortune@gameofthron.es","password":"$2b$12$RfLlYF.8Vxj4MXILL2kvIuyuAO8rN3KR6//UL1a6rNIfNgBaASS66"}
{"_id":{"$oid":"59b99dd8cfa9a34dcd7885f7"},"name":"Loras Tyrell","email":"finn_jones@gameofthron.es","password":"$2b$12$Eb5TLqYLS74pLP9r.2agNe56ht1dvFkQOCODxku8KQmLfldBGa7Cu"}
{"_id":{"$oid":"59b99dd8cfa9a34dcd7885f8"},"name":"Hot Pie","email":"ben_hawkey@gameofthron.es","password":"$2b$12$o99XQuQRvutjESJ8/eqnWe4w8aCYXHFF1cJmZdeKs6acmoPaVlCK."}
{"_id":{"$oid":"59b99dd8cfa9a34dcd7885f9"},"name":"Beric Dondarrion","email":"richard_dormer@gameofthron.es","password":"$2b$12$CHeWRV3bBssK0MR1o4FLcOCmFLaPIPTA0KzKI0aWYDnXCKm98MbJy"}
{"_id":{"$oid":"59b99dd9cfa9a34dcd7885fa"},"name":"Podrick Payne","email":"daniel_portman@gameofthron.es","password":"$2b$12$yYDEeKYMkE2zDjP35/RfZONzFZEuv026MnSRAJ5ZPUoBUhvu6ZRN."}
{"_id":{"$oid":"59b99dd9cfa9a34dcd7885fb"},"name":"Eddison Tollett","email":"ben_crompton@gameofthron.es","password":"$2b$12$adD4J5Cnk/aeVdKC3qnD7ufw7S9sTrvWoiSxNkLqZsr0SWjFj91Wq"}
{"_id":{"$oid":"59b99ddacfa9a34dcd7885fc"},"name":"Yara Greyjoy","email":"gemma_whelan@gameofthron.es","password":"$2b$12$q4rJ2PG4ZJZ1c9PNJeZU1uHH/ckwCh4P0xfu6lGgHIQ8/ugptuQuK"}
{"_id":{"$oid":"59b99ddacfa9a34dcd7885fd"},"name":"Selyse Baratheon","email":"tara_fitzgerald@gameofthron.es","password":"$2b$12$Ri/w5TEI/CsWxvdscYkzhuVzKF0Zy98zgDWO5pmVsXb05jki5PKrG"}
{"_id":{"$oid":"59b99ddacfa9a34dcd7885fe"},"name":"Grey Worm","email":"jacob_anderson@gameofthron.es","password":"$2b$12$Kplgm66WrJlrIxV7g.uQj.zSSY3Q/GuznI6i9z5I9abqcszpTGc0O"}
{"_id":{"$oid":"59b99ddbcfa9a34dcd7885ff"},"name":"Qyburn","email":"anton_lesser@gameofthron.es","password":"$2b$12$Aogz..TkpBMB5UFfgIRSP.dy7DX9qgOi587FSORqRWqApfbw3x7wy"}
{"_id":{"$oid":"59b99ddbcfa9a34dcd788600"},"name":"Olenna Tyrell","email":"diana_rigg@gameofthron.es","password":"$2b$12$8Oh3DVnn8e5NK9nHtX4ZVeprB3O6Zrb8l8KxT2l3rraW11HhxH3di"}
{"_id":{"$oid":"59b99ddbcfa9a34dcd788601"},"name":"Shireen Baratheon","email":"kerry_ingram@gameofthron.es","password":"$2b$12$F8VweX6dNiq4Gymmc7LJsu5U1G0d0wxaf/95CVl5w/4..mFfdgqdG"}
{"_id":{"$oid":"59b99ddbcfa9a34dcd788602"},"name":"Meera Reed","email":"ellie_kendrick@gameofthron.es","password":"$2b$12$SdyXPBMdGScx6DePpPawFeOqcpiwjdHAuTXaPl0mkvWeLzZk6EWTi"}
{"_id":{"$oid":"59b99dddcfa9a34dcd788603"},"name":"Jojen Reed","email":"thomas_brodie-sangster@gameofthron.es","password":"$2b$12$ZAJ8OFWUFNdxhc0xyTd42evQJfL7FnEdk3koHwYtHpDqsrZI61XP."}
{"_id":{"$oid":"59b99dddcfa9a34dcd788604"},"name":"Thoros of Myr","email":"paul_kaye@gameofthron.es","password":"$2b$12$bkA1MM3UEwZ4N0VpCQY68eMY8HKTHWtk2xI2QnG4MuW5UWHlBrF8G"}
{"_id":{"$oid":"59b99ddecfa9a34dcd788605"},"name":"Olly","email":"brenock_o'connor@gameofthron.es","password":"$2b$12$Mp0mG3u/6xuQSe/3/UjO8uHTHUDQUIcV0Iki42vfAqKLaBbYxHjv."}
{"_id":{"$oid":"59b99ddecfa9a34dcd788606"},"name":"Mace Tyrell","email":"roger_ashton-griffiths@gameofthron.es","password":"$2b$12$Z7BRen4BsJqxnBlsRupWou2DlT7CQameOt7V9UlV0vWw3Z2B9sDj6"}
{"_id":{"$oid":"59b99ddecfa9a34dcd788607"},"name":"The Waif","email":"faye_marsay@gameofthron.es","password":"$2b$12$JGlWYUPkZ3xryO9h4x4wdOsnbuLdzbSMSCaJENY6LaLfWYIl86xdG"}
{"_id":{"$oid":"59b99ddfcfa9a34dcd788608"},"name":"Bowen Marsh","email":"michael_condron@gameofthron.es","password":"$2b$12$G8bl4haz.de9f1ohneIcIus3GCj4nNNP7WiufQy6.aoIh01AVk2Xq"}
{"_id":{"$oid":"59b99ddfcfa9a34dcd788609"},"name":"Richard Davis","email":"richard_davis@fakegmail.com","password":"$2b$12$q5/117rbpGoczEDK5LcDjeeOmOnzkVi6h2VIN.1Dbugn6Y5kOo4Ja"}
{"_id":{"$oid":"59b99ddfcfa9a34dcd78860a"},"name":"Greg Powell","email":"greg_powell@fakegmail.com","password":"$2b$12$XpveUB6kIiU3zG5aABw26OitIB7cDBbSUWJAz4WDF4XXyNNJ/mp76"}
{"_id":{"$oid":"59b99de0cfa9a34dcd78860b"},"name":"Sarah Lewis","email":"sarah_lewis@fakegmail.com","password":"$2b$12$5kCUjcP3lvYSzhouVJTpOeCZ7e7Xke8gDoPPg2Uyz39tNKrp9om1a"}
{"_id":{"$oid":"59b99de0cfa9a34dcd78860c"},"name":"Ronald Cox","email":"ronald_cox@fakegmail.com","password":"$2b$12$HhDeE1teAaNqj2Mrfn4f2O57K8z6kVVqtCEr.7Qc5BZR69H6XwRlK"}
{"_id":{"$oid":"59b99de0cfa9a34dcd78860d"},"name":"Emily Ellis","email":"emily_ellis@fakegmail.com","password":"$2b$12$UuCb5RqPEgheoLlwOF/Jb.x9gpFVmD30oUwpSRKljwo8pBUmWT6eG"}
{"_id":{"$oid":"59b99de1cfa9a34dcd78860e"},"name":"Victor Patel","email":"victor_patel@fakegmail.com","password":"$2b$12$VyWh4xdBtuZrhuR933GY6evfU7.py2dJIP9wuSmeiJ.94iP0EO4Pq"}
{"_id":{"$oid":"59b99de1cfa9a34dcd78860f"},"name":"Karina Martin","email":"karina_martin@fakegmail.com","password":"$2b$12$s6XOIsF9p9/p6tZd0nZ1ee5qd6/nc5sL8dd0iES0ZEJySgacjcqD."}
{"_id":{"$oid":"59b99de2cfa9a34dcd788610"},"name":"Robert Jordan","email":"robert_jordan@fakegmail.com","password":"$2b$12$OumeM9/x5dBn5RLd/5QUNu8poyzsVbhJtLs2S02JqCwzubbbBK902"}
{"_id":{"$oid":"59b99de2cfa9a34dcd788611"},"name":"Javier Smith","email":"javier_smith@fakegmail.com","password":"$2b$12$ce2znqUW43.BjKQaTS5tiekhqZuCLQHOguozLkVm4P.WM8VlrEhPe"}
{"_id":{"$oid":"59b99de2cfa9a34dcd788612"},"name":"Amy Phillips","email":"amy_phillips@fakegmail.com","password":"$2b$12$z.IU36O/1r25xdhI.Gdw1e2dLXSjIgIMNrxginP0/iVIlZcCWiyaK"}
{"_id":{"$oid":"59b99de3cfa9a34dcd788613"},"name":"Jason Smith","email":"jason_smith@fakegmail.com","password":"$2b$12$l2JMT18BcA8.R3tUxVDKj.9/jwre8CAccr21PvJ576nJ8Pvegxn0m"}
{"_id":{"$oid":"59b99de3cfa9a34dcd788614"},"name":"Cameron Duran","email":"cameron_duran@fakegmail.com","password":"$2b$12$50w2j63ATGmhVOh2rgdjv.wOd9TV0Jb9Xk/Anms0fxVSvGMf5MwvK"}
{"_id":{"$oid":"59b99de3cfa9a34dcd788615"},"name":"Megan Turner","email":"megan_turner@fakegmail.com","password":"$2b$12$nR8x.s7PmEQttaF7RS33euSLEZzuu0G2UhSK.PeHJEZEjcK.J3Xq6"}
{"_id":{"$oid":"59b99de4cfa9a34dcd788616"},"name":"Megan Richards","email":"megan_richards@fakegmail.com","password":"$2b$12$iDxjjcgBA.Q9zjTlOD4KJuhPJx6gw5GecbDWCbVmfzzv2rqNbC2vC"}
{"_id":{"$oid":"59b99de4cfa9a34dcd788617"},"name":"Thomas Buckley","email":"thomas_buckley@fakegmail.com","password":"$2b$12$.zRRXpjiT0uuR13kt85CDesUMJPIEK1mziudzedd7S10YVAd31586"}
{"_id":{"$oid":"59b99de4cfa9a34dcd788618"},"name":"Lisa Rasmussen","email":"lisa_rasmussen@fakegmail.com","password":"$2b$12$HHK6sMwGNXZlOHOpFXcHpuS3qS8/XA2202y7ZIlTJ.6y5E6SUl7Yy"}
{"_id":{"$oid":"59b99de5cfa9a34dcd788619"},"name":"Connie Johnson","email":"connie_johnson@fakegmail.com","password":"$2b$12$tA3NXW5mHAru7YbIrW6x3.T3OweDVjBwk6wf/ukXBiwxAZXi3R5m2"}
{"_id":{"$oid":"59b99de5cfa9a34dcd78861a"},"name":"Victor Fleming","email":"victor_fleming@fakegmail.com","password":"$2b$12$DQSGcwfMllp0HTDNI6QLGeI41zrqprdlEnIXf6RHdpOCMBc37wzV."}
{"_id":{"$oid":"59b99de6cfa9a34dcd78861b"},"name":"Brandon Hardy","email":"brandon_hardy@fakegmail.com","password":"$2b$12$7qxHDP2xlgztpQITlwjlBugE2ned0nRmm22Gu1mK34fZJvh5IE4SO"}
{"_id":{"$oid":"59b99de6cfa9a34dcd78861c"},"name":"Kathryn Sosa","email":"kathryn_sosa@fakegmail.com","password":"$2b$12$naMKKiQlGxdNh1WMCa6ws.Yo1nEr5OWBILzMYEDlt.fw.UmOVnMhu"}
{"_id":{"$oid":"59b99de6cfa9a34dcd78861d"},"name":"Mrs. Ariana Nunez","email":"mrs._ariana_nunez@fakegmail.com","password":"$2b$12$KN9tlEa1K65zgHHG7zh2KePPpU0/NC1o/WN3RoIOaHBvWEoPq2DMC"}
{"_id":{"$oid":"59b99de7cfa9a34dcd78861e"},"name":"Yvette Roth","email":"yvette_roth@fakegmail.com","password":"$2b$12$JmceK9VLl7aY/uF9.ZdLTOuj0y5xR3jjvDZVyFCCPQT/lly5IocIm"}
{"_id":{"$oid":"59b99de7cfa9a34dcd78861f"},"name":"Kelsey Smith","email":"kelsey_smith@fakegmail.com","password":"$2b$12$S.moHRDfHWLM.F5IasBPQek/y76l0ejX.a5EnPQMbtpECI3tWXS/y"}
{"_id":{"$oid":"59b99de7cfa9a34dcd788620"},"name":"Keith Phillips","email":"keith_phillips@fakegmail.com","password":"$2b$12$oXW3cr3lIY37/Ps3uSZBj.rFQoFjZAuFvtHNyxHyocIIlI9lT93MO"}
{"_id":{"$oid":"59b99de7cfa9a34dcd788621"},"name":"Morgan Smith","email":"morgan_smith@fakegmail.com","password":"$2b$12$vm836TjgawCzAglcRq/GWOPJpAOT9W.w0tEAGqoIvDxMRn.rfZCQK"}
{"_id":{"$oid":"59b99de8cfa9a34dcd788622"},"name":"Anthony Thompson","email":"anthony_thompson@fakegmail.com","password":"$2b$12$Ki.7nartO8MscZ53cV5jEuLa83JD8OKd6sgCqxird98ijmWRTRcrC"}
{"_id":{"$oid":"59b99de8cfa9a34dcd788623"},"name":"Joshua Kent","email":"joshua_kent@fakegmail.com","password":"$2b$12$xSofV4dlicgiRA9yRtB9BescTvQFusNdde7/yz6AQ8lRKKMTdhRLW"}
{"_id":{"$oid":"59b99deacfa9a34dcd788624"},"name":"Brenda Martin","email":"brenda_martin@fakegmail.com","password":"$2b$12$H.QWgwnd5SwchVniifWfS.BmBefv6FhBBKqjcDlI20ZdqgFvIy3F2"}
{"_id":{"$oid":"59b99deacfa9a34dcd788625"},"name":"Garrett Obrien","email":"garrett_obrien@fakegmail.com","password":"$2b$12$ElY14tB9rHL3L4yhrY7gcOGr0u0eFZ5Eb6IoG3eH15sqAeAqbco/a"}
{"_id":{"$oid":"59b99deacfa9a34dcd788626"},"name":"Lori Franklin","email":"lori_franklin@fakegmail.com","password":"$2b$12$h25/G5rXZejwsAhn7rvYIuuLzwnayZcf4yX0CV02gDh0dA14UyVsy"}
{"_id":{"$oid":"59b99debcfa9a34dcd788627"},"name":"Kenneth Chandler","email":"kenneth_chandler@fakegmail.com","password":"$2b$12$Bo8ObYfsGdSsJrcdf/bat.NFhp4ITDrsyZvYlTmZWh.zrReVKVH4u"}
{"_id":{"$oid":"59b99debcfa9a34dcd788628"},"name":"Daniel Simmons","email":"daniel_simmons@fakegmail.com","password":"$2b$12$o2vaieyGbqZ5a.BhIB3e9.cZ1dEO3Ob/3gc1Ef1/QX4cI9vnMraUC"}
{"_id":{"$oid":"59b99debcfa9a34dcd788629"},"name":"Paula Sullivan","email":"paula_sullivan@fakegmail.com","password":"$2b$12$6eM.dlL7Wi84eYUkwzkU.erG/JqAvwOKSGn5V1bG6HLfIFrpTYaXi"}
{"_id":{"$oid":"59b99deccfa9a34dcd78862a"},"name":"Richard Schmidt","email":"richard_schmidt@fakegmail.com","password":"$2b$12$3odZLmzPAoFZc/S3mVRCWOimTOx.RGTY1CP/jJBsW42F0zfbwOXQK"}
{"_id":{"$oid":"59b99deccfa9a34dcd78862b"},"name":"Anthony Smith","email":"anthony_smith@fakegmail.com","password":"$2b$12$OLhPk6TMdQ9rY/LIMjsaa.Pfb6IlCQgZK2BCx37lYqotgy9tHo3F6"}
{"_id":{"$oid":"59b99dedcfa9a34dcd78862c"},"name":"Michael Day","email":"michael_day@fakegmail.com","password":"$2b$12$1BdlPh4Imkw8kn7aCgEWsOCt1DED7cFTMlVOf62k6lGxEvQEe1L56"}
{"_id":{"$oid":"59b99dedcfa9a34dcd78862d"},"name":"Mercedes Tyler","email":"mercedes_tyler@fakegmail.com","password":"$2b$12$ONDwIwR9NKF1Tp5GjGI12e8OFMxPELoFrk4x4Q3riJGWY6jl/UZAa"}
{"_id":{"$oid":"59b99dedcfa9a34dcd78862e"},"name":"Kristen Schmidt","email":"kristen_schmidt@fakegmail.com","password":"$2b$12$lUexqpKoc6RNXLAHGPZ50OLWr3oKfrJW9Vg.q6s7DrCs5X0blJYtW"}
{"_id":{"$oid":"59b99deecfa9a34dcd78862f"},"name":"Justin Williams","email":"justin_williams@fakegmail.com","password":"$2b$12$5GAeUijkM4g3s5yBZniXxOYlA13vLLt.CPkXLCs3jlfsYJrgJ37fy"}
{"_id":{"$oid":"59b99deecfa9a34dcd788630"},"name":"John Roman","email":"john_roman@fakegmail.com","password":"$2b$12$UW2RqzQlgLcPNLn3gxY16uMhqso5GgeAzYfAQVY2yplhacxZ.daSy"}
{"_id":{"$oid":"59b99defcfa9a34dcd788631"},"name":"April Cole","email":"april_cole@fakegmail.com","password":"$2b$12$DhQx.0ywiZK7v4UrN6YeXuS06U2JHNM2owUHxbL8aXlobGT7E65Ke"}
{"_id":{"$oid":"59b99defcfa9a34dcd788632"},"name":"Kimberly Gates","email":"kimberly_gates@fakegmail.com","password":"$2b$12$fE/FzdNHaDJS2nW5jPziHe0lgKcVqPEF6B2X7vCx35RgvEVp2DS7y"}
{"_id":{"$oid":"59b99defcfa9a34dcd788633"},"name":"Denise Davidson","email":"denise_davidson@fakegmail.com","password":"$2b$12$kjWPMnQwGlwe7NGI0NdE9uq3KGvJ8jA0bJILkEUXFE9tzPVjwzJ1a"}
{"_id":{"$oid":"59b99df0cfa9a34dcd788634"},"name":"Michael Moore","email":"michael_moore@fakegmail.com","password":"$2b$12$9rCFOeptsZ6eFBzoprKRFOKS.NQteHtfWurzBkndHNt9DLVdAZGsW"}
{"_id":{"$oid":"59b99df0cfa9a34dcd788635"},"name":"Lisa Silva","email":"lisa_silva@fakegmail.com","password":"$2b$12$K8ZpLpGQUUFev/fxmJSlueIdVJ3.7CNYRNERCRae5B1auB7SLBTu2"}
{"_id":{"$oid":"59b99df0cfa9a34dcd788636"},"name":"Andrea Le","email":"andrea_le@fakegmail.com","password":"$2b$12$JS87HWuL2y0P1E6kYrcbKOKx22.wsKEdLtS0F734/vKdhuduLM8Ve"}
{"_id":{"$oid":"59b99df1cfa9a34dcd788637"},"name":"Edward Barrett","email":"edward_barrett@fakegmail.com","password":"$2b$12$Jzx8f0IiHYFcdU/PEceFJeS1HjC43HTL2aBhKQt8uUM2zfJf3p7Ki"}
{"_id":{"$oid":"59b99df1cfa9a34dcd788638"},"name":"Christian Williams","email":"christian_williams@fakegmail.com","password":"$2b$12$D2/B/KGdHRduXiT0/OX5Yu0YMfubTWOOaCjuOyQrDUMvq2Eju10ny"}
{"_id":{"$oid":"59b99df2cfa9a34dcd788639"},"name":"Jason Hernandez","email":"jason_hernandez@fakegmail.com","password":"$2b$12$fmvh3F8TRhntCXSCTb/oG.MJlZmXwStdf/UfCSFnSxSsbJb0Bsmwi"}
{"_id":{"$oid":"59b99df2cfa9a34dcd78863a"},"name":"Patricia Good","email":"patricia_good@fakegmail.com","password":"$2b$12$t9xIBFolWLphJBO9VCpV4uoZDx/TOhg7N436kBe72hgDMxsGvQr3m"}
{"_id":{"$oid":"59b99df2cfa9a34dcd78863b"},"name":"Barbara Gonzalez","email":"barbara_gonzalez@fakegmail.com","password":"$2b$12$qxLcDfjy7RdjfJbrFRHntu0kzVnXzJKED0on8TZ84dLlSCKKkaJt2"}
{"_id":{"$oid":"59b99df3cfa9a34dcd78863c"},"name":"Denise Bryant","email":"denise_bryant@fakegmail.com","password":"$2b$12$Dcm7ncpCt0PVR4HFux4hDetCNL3E3mQg9GKqJHR/Nz/O40HCgEJzu"}
{"_id":{"$oid":"59b99df4cfa9a34dcd78863d"},"name":"Victoria Sanders","email":"victoria_sanders@fakegmail.com","password":"$2b$12$/2aikvro4gXgcp01Z8qIj.s2s53lpVcLQRbG/9VNbHa4i3ajo5dc."}
{"_id":{"$oid":"59b99df4cfa9a34dcd78863e"},"name":"Taylor Scott","email":"taylor_scott@fakegmail.com","password":"$2b$12$rIJO4MKGZFHKyPeU9X8hSOsCjL3Isa9Gv8rZ7rzM7kKA3XUd1PAlO"}
{"_id":{"$oid":"59b99df5cfa9a34dcd78863f"},"name":"Taylor Hill","email":"taylor_hill@fakegmail.com","password":"$2b$12$5NRO3TpZti62ZN2rSlxYoOurfMQAUEQ4oIufrfAhcsSqGp4eKF4Gi"}
{"_id":{"$oid":"59b99df5cfa9a34dcd788640"},"name":"Melissa Jones","email":"melissa_jones@fakegmail.com","password":"$2b$12$S6.mFqBn8QMRtyeJUJbRcOwkrgtjHyg7GkmxilnWvOzRtPar.d1K."}
{"_id":{"$oid":"59b99df5cfa9a34dcd788641"},"name":"Christopher Robinson","email":"christopher_robinson@fakegmail.com","password":"$2b$12$Bop6XQ2mLRjsMXPjKUEtcuIw9751lV.cKj/eXM1ZwSetsku3sa04W"}
{"_id":{"$oid":"59b99df6cfa9a34dcd788642"},"name":"Amy Ramirez","email":"amy_ramirez@fakegmail.com","password":"$2b$12$LN9OzMA5sX3bQnMjkkWa.OjMrjif.LIbqx7YSf52FtQ9QcBlUS8ee"}
{"_id":{"$oid":"59b99df7cfa9a34dcd788643"},"name":"Phillip Collins","email":"phillip_collins@fakegmail.com","password":"$2b$12$3XQmnWfaMh9bwJMXAdJLheLLiU7bCVATlDsdo4BREnIQFbfCxUOcK"}
{"_id":{"$oid":"59b99df7cfa9a34dcd788644"},"name":"Jerry Cabrera","email":"jerry_cabrera@fakegmail.com","password":"$2b$12$HEimsC0UBidI9AYqPU4Mr.P8UZVO6zsZm2VUFVeuA467fdqp8WJDu"}
{"_id":{"$oid":"59b99df7cfa9a34dcd788645"},"name":"Ms. Cathy Miller","email":"ms._cathy_miller@fakegmail.com","password":"$2b$12$wQ02A.LLpeLLEItcBZF2IOOSlds3VjdaXOI2XRt/ElyG2852ITbiW"}
{"_id":{"$oid":"59b99df8cfa9a34dcd788646"},"name":"Lisa Russo","email":"lisa_russo@fakegmail.com","password":"$2b$12$pOdj440b9rps82eCfXzCiONHjBo9zowp62kNDdQSRVPMwGJmxAk0W"}
{"_id":{"$oid":"59b99df8cfa9a34dcd788647"},"name":"Thomas Morris","email":"thomas_morris@fakegmail.com","password":"$2b$12$IfMqv/fVHb3KZtQxKtUXP.C.Uh9rNI9qKWB4eZ6d2YiEl5P3XnDk."}
{"_id":{"$oid":"59b99df8cfa9a34dcd788648"},"name":"Elizabeth Wiggins","email":"elizabeth_wiggins@fakegmail.com","password":"$2b$12$UGbyi1WBFHu9xqTYp2nxzuGtWaolgxyj/7r2kXjSltr7s8jzr8RFm"}
{"_id":{"$oid":"59b99df9cfa9a34dcd788649"},"name":"Nicholas Webster","email":"nicholas_webster@fakegmail.com","password":"$2b$12$LLuOi5eMoy6hWIC61dolKu9/0bxRKsL0kwWfcJ8A0qr.SX/AR5aCi"}
{"_id":{"$oid":"59b99df9cfa9a34dcd78864a"},"name":"Teresa Thomas","email":"teresa_thomas@fakegmail.com","password":"$2b$12$vQQlmv3ubYNZh8HfSXmu4.peazChIJo15UEnLpQz9O90nr8U/qlfS"}
{"_id":{"$oid":"59b99df9cfa9a34dcd78864b"},"name":"Catherine Romero","email":"catherine_romero@fakegmail.com","password":"$2b$12$XVWuCkFmEypxLhpe6OnZdeZ2HcO/mD.q0bcDun5izEPMDCSTGW5AO"}
{"_id":{"$oid":"59b99dfacfa9a34dcd78864c"},"name":"Julia Nichols","email":"julia_nichols@fakegmail.com","password":"$2b$12$HZbkbktkRTaV7LiwLxW3D.gDV5lQAy05Wumz981D7gwvSoAc9uJxq"}
{"_id":{"$oid":"59b99dfacfa9a34dcd78864d"},"name":"Heather Leonard","email":"heather_leonard@fakegmail.com","password":"$2b$12$/mzEsE5kIBX1sWGWlp4GuOilNW.h5ZSIWVgYh.kbt3i0LG3BPY3hy"}
{"_id":{"$oid":"59b99dfbcfa9a34dcd78864e"},"name":"Melissa Young","email":"melissa_young@fakegmail.com","password":"$2b$12$iei9pWuCZ6wF/TJhVJ1gE.k7dkc.0NiHgR6/lJCn4ANkaBkdKS/Wy"}
{"_id":{"$oid":"59b99dfbcfa9a34dcd78864f"},"name":"John Rice","email":"john_rice@fakegmail.com","password":"$2b$12$Yg0bT/yCT5fX8xn.D4Fj3.slpd7tccYWKgRGghrLglX5Faz6Fb86G"}
{"_id":{"$oid":"59b99dfccfa9a34dcd788650"},"name":"Blake Sellers","email":"blake_sellers@fakegmail.com","password":"$2b$12$g2u20yqqpzbNipA6lfIoBO3Cs9jM7jsWBhDheF1OsthHpLfEcD2Gm"}
{"_id":{"$oid":"59b99dfdcfa9a34dcd788651"},"name":"Theresa Holmes","email":"theresa_holmes@fakegmail.com","password":"$2b$12$1b.0k6/Ox.r9CHmPYPIs2eH5FZolXLc5e9E4IyTJd3YkzAVTB1Dta"}
{"_id":{"$oid":"59b99dfdcfa9a34dcd788652"},"name":"Bradley Brooks","email":"bradley_brooks@fakegmail.com","password":"$2b$12$YvZMPevRPXozhmujYwhFe.oTEHhdvHrJEviyXaXUjLsDr6tkHBoC."}
{"_id":{"$oid":"59b99dfdcfa9a34dcd788653"},"name":"Thomas Green","email":"thomas_green@fakegmail.com","password":"$2b$12$6u6dECDnaDoNehg1gU14KOcGAtmMnKcnsSv7U2W693xk/UTKF.of6"}
{"_id":{"$oid":"59b99dfecfa9a34dcd788654"},"name":"Jonathon Mccullough","email":"jonathon_mccullough@fakegmail.com","password":"$2b$12$uZlaQmlnL501KsvPJSCJbO47tz9.8GB8Hl0Xu31xURToXMP8dWzOi"}
{"_id":{"$oid":"59b99dfecfa9a34dcd788655"},"name":"Jeffrey Roberts","email":"jeffrey_roberts@fakegmail.com","password":"$2b$12$UrTFJ6Xnr043.QRwFVlqgudHC6GPSjejaldJw2/UFsR.dyPwj7cxK"}
{"_id":{"$oid":"59b99dfecfa9a34dcd788656"},"name":"Jose Hall","email":"jose_hall@fakegmail.com","password":"$2b$12$ghmMMtvS1Wcmf9.UEF5ep.sAU5KS2.GUpgK41hiPh4EzyJYCy2P42"}
{"_id":{"$oid":"59b99e00cfa9a34dcd788657"},"name":"Jennifer Frazier","email":"jennifer_frazier@fakegmail.com","password":"$2b$12$Xm1ktF5woIqEw5q00xCnZO.PwJDWi9VIrbbrMemqv5zzF1zJGN2AC"}
{"_id":{"$oid":"59b99e00cfa9a34dcd788658"},"name":"Jamie Santana","email":"jamie_santana@fakegmail.com","password":"$2b$12$KhXBuPIzyxoqMjpTn4h4ku9Dky3bofFDVNrMD5T6Z2Dd1j1wWAGe2"}
{"_id":{"$oid":"59b99e01cfa9a34dcd788659"},"name":"Anthony Cline","email":"anthony_cline@fakegmail.com","password":"$2b$12$JWTRRBJgXOv.peG2HDFHeORuwvOaZigFtxhUSDhbpPEFRRuhS19F2"}
{"_id":{"$oid":"59b99e01cfa9a34dcd78865a"},"name":"Donna Russell","email":"donna_russell@fakegmail.com","password":"$2b$12$5PICbqGRxD2Mj5ljv0wQnu6d.a4mNPoma1GtMvYOHE.M7bz6vIu4e"}
{"_id":{"$oid":"59b99e02cfa9a34dcd78865b"},"name":"Blake Fitzgerald","email":"blake_fitzgerald@fakegmail.com","password":"$2b$12$.ilQEC/iyR4FhnMA1PmzVe.kMkAbI7htSZJKquTjnaVFH.RDmsP32"}
{"_id":{"$oid":"59b99e02cfa9a34dcd78865c"},"name":"Mary Mitchell","email":"mary_mitchell@fakegmail.com","password":"$2b$12$rT8TmryDDeU446M.g1vVCePtByl85Y/vZ/awAn3eOXCke.bKXHr9G"}
{"_id":{"$oid":"59b99e02cfa9a34dcd78865d"},"name":"Deborah Kennedy","email":"deborah_kennedy@fakegmail.com","password":"$2b$12$lJL2fO48ZrLRhZTf1FBVv.eaaQQ6FSSUh/SwAqvRkcCgM1lZp4moG"}
{"_id":{"$oid":"59b99e02cfa9a34dcd78865e"},"name":"Lori Blankenship","email":"lori_blankenship@fakegmail.com","password":"$2b$12$SQUa.3cIKcazfuUOpd9/huR.VeFAH.uR.ESvIMfbMW1YQjZx47Tw6"}
{"_id":{"$oid":"59b99e03cfa9a34dcd78865f"},"name":"Paul Bailey","email":"paul_bailey@fakegmail.com","password":"$2b$12$m4x95MQ5iSqH.SmcxmBeOuiDYUi9iMcjT1VHXiwKBPHtQ9MNrKnru"}
{"_id":{"$oid":"59b99e03cfa9a34dcd788660"},"name":"John Bishop","email":"john_bishop@fakegmail.com","password":"$2b$12$ifnm6ZFlRQaV4YFe2WcpKuyYfp2eW.42QECH7dkEoD0WeTFpQ8pCe"}
{"_id":{"$oid":"59b99e04cfa9a34dcd788661"},"name":"Nichole Miller","email":"nichole_miller@fakegmail.com","password":"$2b$12$RwG1XZMs3MT/kfdH0L2EWOrfUkOuDkMl./KT.xld4Wyie9w87CM1a"}
{"_id":{"$oid":"59b99e04cfa9a34dcd788662"},"name":"Yolanda Owen","email":"yolanda_owen@fakegmail.com","password":"$2b$12$lmpyYO8lCI.Y/J5AZF6/4u8XyEnCoZXsZzf7l9f7ECNbktqH2KZO."}
{"_id":{"$oid":"59b99e04cfa9a34dcd788663"},"name":"Nicholas Johnson","email":"nicholas_johnson@fakegmail.com","password":"$2b$12$hdzNySj4l/tZR4op5oQXb.FStH3u7ZHjmhhtrpQFIEe39NkBS6R1y"}
{"_id":{"$oid":"59b99e05cfa9a34dcd788664"},"name":"Desiree Pierce","email":"desiree_pierce@fakegmail.com","password":"$2b$12$6ndntifLUo9dshFeTkyOEO.xskWXa1n2q5dcl9uOglKz3cd0vMeJm"}
{"_id":{"$oid":"59b99e06cfa9a34dcd788665"},"name":"Connie Barton","email":"connie_barton@fakegmail.com","password":"$2b$12$dFHzE0VmGHX7K7Je4QWZ0ucv4XX7zup9FWvrF8NFUHlm4k2a4z2se"}
{"_id":{"$oid":"59b99e06cfa9a34dcd788666"},"name":"Patrick Knight","email":"patrick_knight@fakegmail.com","password":"$2b$12$GrKhwH1qeeJNGcGLmjg9f.k7ruCRxGUbfm4z3mgzGkiXXZVvKGCwy"}
{"_id":{"$oid":"59b99e07cfa9a34dcd788667"},"name":"Eric Navarro","email":"eric_navarro@fakegmail.com","password":"$2b$12$ULJ9tL7jh8yPXNDmCJi4C.mzkxzLfIQXakq3td9dJQs3io/Zg/AE2"}
{"_id":{"$oid":"59b99e07cfa9a34dcd788668"},"name":"Jordan Medina","email":"jordan_medina@fakegmail.com","password":"$2b$12$QcSxfXU.jBizvmaU/zc33eIChz4lVAcQalzCupFBv3eGYEsVhJazW"}
{"_id":{"$oid":"59b99e08cfa9a34dcd788669"},"name":"Donna Smith","email":"donna_smith@fakegmail.com","password":"$2b$12$LYIyq5Bsszh3/8efEYmJRuWDqhOeg8K5czQwSLxEBhOTyhOX34JEy"}
{"_id":{"$oid":"59b99e08cfa9a34dcd78866a"},"name":"Shawn Mccormick","email":"shawn_mccormick@fakegmail.com","password":"$2b$12$fVJEFj7SXlqT0EmE9k00FuZLNH52NFSPriUqm8GGT6QQmuzrsMwUC"}
{"_id":{"$oid":"59b99e09cfa9a34dcd78866b"},"name":"Anthony Hurst","email":"anthony_hurst@fakegmail.com","password":"$2b$12$9M2cew6pOM.35LY474rMkeVD4WxfvF2lDtVg60jZrlMdbaexrIfwK"}
{"_id":{"$oid":"59b99e09cfa9a34dcd78866c"},"name":"Ashlee Hart","email":"ashlee_hart@fakegmail.com","password":"$2b$12$S707opDk6HG/Lqk7MaHeQ.1N36I6kEUOhRv/RQEHZUbw89xAuO6Ju"}
{"_id":{"$oid":"5db1c37e4a68c31f10cf0a98"},"name":"Magical Mr. Mistoffelees","email":"magicz@cats.com","password":"somehashedpw"}
{"_id":{"$oid":"5db1c37e4a68c31f10cf0a9f"},"name":"foo","email":"foobaz@bar.com","password":"foobar","preferences":{}}

View File

@ -0,0 +1,46 @@
#!/bin/bash
echo "📥 Getting `mongosh` dependancies..."
apt-get install -s -y gnupg
wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-6.0.list
apt-get update && apt-get -s upgrade
apt-get install -y mongodb-mongosh
echo "🕵️‍♀️ Inspecting Collections..."
# Collections to analyze
if [[ -z "${MONGO_SELECT_COLLECTIONS}" ]]; then
# Get all collections
collections=$(mongosh --quiet --username ${MONGO_USERNAME} --password ${MONGO_PASSWORD} --authenticationDatabase=admin --eval "db.getCollectionNames()" ${MONGO_DATABASE} | tr -d '[\[\]"\ \n]')
else
# Only collections in env vars
collections=${MONGO_SELECT_COLLECTIONS}
fi
IFS=',' read -ra COLLECTIONS <<< "$collections"
echo "📚 Collections for analysis: ${COLLECTIONS[@]}"
echo '---------------------------------'
# Query each collection and run through variety
mkdir -p /schema_exports/analysis
for collection in "${COLLECTIONS[@]}"; do
echo "🔍 Analyzing ${collection}..."
# Run variety on the collection
# Update this --eval query to match your needs (example, filter or limit how many records to analyze)
mongosh ${MONGO_DATABASE} --quiet --eval "var collection = '${collection//\'/}', outputFormat='json'" --username ${MONGO_USERNAME} --password ${MONGO_PASSWORD} --authenticationDatabase=admin /schema_sampler/variety.js > "/schema_exports/analysis/${collection//\'/}.json"
echo "${collection} analysis complete..."
echo "💿 Converting analysis to validation schema..."
# Convert the variety output to a validation jsonschema
node /schema_sampler/validation_exporter.js ${collection//\'/}
echo "${collection} validation schema created..."
# Plug the json schema back into MongoDB if the user has selected that option
if [[ "${MONGO_UPDATE_COLLECTIONS}" == "true" ]]; then
echo "🔄 Updating ${collection} with validation schema in MongoDB..."
schema=$(cat /schema_exports/validation_schema/${collection//\'/}.json)
mongosh ${MONGO_DATABASE} --quiet --eval "db.runCommand({ collMod: '${collection//\'/}', validator: ${schema}, validationAction: 'warn' })" --username ${MONGO_USERNAME} --password ${MONGO_PASSWORD} --authenticationDatabase=admin
echo "${collection} validation schema updated in MongoDB..."
fi
echo '---------------------------------'
done
echo "✅ Collection analysis and update complete..."

View File

@ -0,0 +1,55 @@
const fs = require("fs");
let collection = process.argv[2];
let rawdata = fs.readFileSync(`/schema_exports/analysis/${collection}.json`);
let analysisData = JSON.parse(rawdata);
let schema = {
$jsonSchema: {
bsonType: "object",
required: [""],
properties: {},
},
};
let output = {};
const createTemplate = (obj) => {
obj.forEach((element) => {
const keys = element._id.key.split(".");
const typeKeys = Object.keys(element.value.types);
let type;
if (typeKeys.length > 1) {
type = "string";
} else {
type = typeKeys[0].toLowerCase();
}
const convertedType = type === "objectid" ? "objectId" : type;
let subObj = output;
for (let i = 0; i < keys.length; i++) {
if (!subObj.properties) {
subObj.properties = {};
}
if (!subObj.properties[keys[i]]) {
if (i < keys.length - 1 || convertedType === "object") {
subObj.properties[keys[i]] = {};
} else {
subObj.properties[keys[i]] = { bsonType: convertedType };
}
}
if (i === keys.length - 1 && convertedType === "object") {
subObj.properties[keys[i]].bsonType = convertedType;
subObj = subObj.properties[keys[i]];
} else {
subObj = subObj.properties[keys[i]];
}
}
});
};
createTemplate(analysisData);
schema.$jsonSchema = output;
fs.writeFileSync(
`/schema_exports/validation_schema/${collection}.json`,
JSON.stringify(schema, null, 2)
);

View File

@ -0,0 +1,421 @@
/* Variety: A MongoDB Schema Analyzer
This tool helps you get a sense of your application's schema, as well as any
outliers to that schema. Particularly useful when you inherit a codebase with
data dump and want to quickly learn how the data's structured. Also useful for
finding rare keys.
Please see https://github.com/variety/variety for details.
Released by Maypop Inc, © 20122023, under the MIT License. */
(function () {
'use strict'; // wraps everything for which we can use strict mode -JC
var log = function(message) {
// print(message);
};
log('Variety: A MongoDB Schema Analyzer');
log('Version 1.5.1, released 02 October 2017');
var dbs = [];
var emptyDbs = [];
if (typeof slaveOk !== 'undefined') {
if (slaveOk === true) {
db.getMongo().setSlaveOk();
}
}
var knownDatabases = db.adminCommand('listDatabases').databases;
if(typeof knownDatabases !== 'undefined') { // not authorized user receives error response (json) without databases key
knownDatabases.forEach(function(d){
if(db.getSiblingDB(d.name).getCollectionNames().length > 0) {
dbs.push(d.name);
}
if(db.getSiblingDB(d.name).getCollectionNames().length === 0) {
emptyDbs.push(d.name);
}
});
if (emptyDbs.indexOf(db.getName()) !== -1) {
throw 'The database specified ('+ db +') is empty.\n'+
'Possible database options are: ' + dbs.join(', ') + '.';
}
if (dbs.indexOf(db.getName()) === -1) {
throw 'The database specified ('+ db +') does not exist.\n'+
'Possible database options are: ' + dbs.join(', ') + '.';
}
}
var collNames = db.getCollectionNames().join(', ');
if (typeof collection === 'undefined') {
throw 'You have to supply a \'collection\' variable, à la --eval \'var collection = "animals"\'.\n'+
'Possible collection options for database specified: ' + collNames + '.\n'+
'Please see https://github.com/variety/variety for details.';
}
if (db.getCollection(collection).countDocuments({}, {limit: 1}) === 0) {
throw 'The collection specified (' + collection + ') in the database specified ('+ db +') does not exist or is empty.\n'+
'Possible collection options for database specified: ' + collNames + '.';
}
var readConfig = function(configProvider) {
var config = {};
var read = function(name, defaultValue) {
var value = typeof configProvider[name] !== 'undefined' ? configProvider[name] : defaultValue;
config[name] = value;
log('Using '+name+' of ' + JSON.stringify(value));
};
read('collection', null);
read('query', {});
read('limit', db.getCollection(config.collection).find(config.query).count());
read('maxDepth', 99);
read('sort', {_id: -1});
read('outputFormat', 'ascii');
read('persistResults', false);
read('resultsDatabase', 'varietyResults');
read('resultsCollection', collection + 'Keys');
read('resultsUser', null);
read('resultsPass', null);
read('logKeysContinuously', false);
read('excludeSubkeys', []);
read('arrayEscape', 'XX');
read('lastValue', false);
//Translate excludeSubkeys to set like object... using an object for compatibility...
config.excludeSubkeys = config.excludeSubkeys.reduce(function (result, item) { result[item+'.'] = true; return result; }, {});
return config;
};
var config = readConfig(this);
var PluginsClass = function(context) {
var parsePath = function(val) { return val.slice(-3) !== '.js' ? val + '.js' : val;};
var parseConfig = function(val) {
var config = {};
val.split('&').reduce(function(acc, val) {
var parts = val.split('=');
acc[parts[0]] = parts[1];
return acc;
}, config);
return config;
};
if(typeof context.plugins !== 'undefined') {
this.plugins = context.plugins.split(',')
.map(function(path){return path.trim();})
.map(function(definition){
var path = parsePath(definition.split('|')[0]);
var config = parseConfig(definition.split('|')[1] || '');
context.module = context.module || {};
load(path);
var plugin = context.module.exports;
plugin.path = path;
if(typeof plugin.init === 'function') {
plugin.init(config);
}
return plugin;
}, this);
} else {
this.plugins = [];
}
this.execute = function(methodName) {
var args = Array.prototype.slice.call(arguments, 1);
var applicablePlugins = this.plugins.filter(function(plugin){return typeof plugin[methodName] === 'function';});
return applicablePlugins.map(function(plugin) {
return plugin[methodName].apply(plugin, args);
});
};
log('Using plugins of ' + JSON.stringify(this.plugins.map(p => p.path)));
return this;
};
var $plugins = new PluginsClass(this);
$plugins.execute('onConfig', config);
var varietyTypeOf = function(thing) {
if (!arguments.length) { throw 'varietyTypeOf() requires an argument'; }
if (typeof thing === 'undefined') {
return 'undefined';
} else if (typeof thing !== 'object') {
// the messiness below capitalizes the first letter, so the output matches
// the other return values below. -JC
var typeofThing = typeof thing; // edgecase of JSHint's "singleGroups"
return typeofThing[0].toUpperCase() + typeofThing.slice(1);
} else {
if (thing && thing.constructor === Array) {
return 'Array';
} else if (thing === null) {
return 'null';
} else if (thing instanceof Date) {
return 'Date';
} else if(thing instanceof NumberLong) {
return 'NumberLong';
} else if (thing instanceof ObjectId) {
return 'ObjectId';
} else if (thing instanceof BinData) {
var binDataTypes = {};
binDataTypes[0x00] = 'generic';
binDataTypes[0x01] = 'function';
binDataTypes[0x02] = 'old';
binDataTypes[0x03] = 'UUID';
binDataTypes[0x04] = 'UUID';
binDataTypes[0x05] = 'MD5';
binDataTypes[0x80] = 'user';
return 'BinData-' + binDataTypes[thing.subtype()];
} else {
return 'Object';
}
}
};
//flattens object keys to 1D. i.e. {'key1':1,{'key2':{'key3':2}}} becomes {'key1':1,'key2.key3':2}
//we assume no '.' characters in the keys, which is an OK assumption for MongoDB
var serializeDoc = function(doc, maxDepth, excludeSubkeys) {
var result = {};
//determining if an object is a Hash vs Array vs something else is hard
//returns true, if object in argument may have nested objects and makes sense to analyse its content
function isHash(v) {
var isArray = Array.isArray(v);
var isObject = typeof v === 'object';
var specialObject = v instanceof Date ||
v instanceof ObjectId ||
v instanceof BinData ||
v instanceof NumberLong;
return !specialObject && (isArray || isObject);
}
var arrayRegex = new RegExp('\\.' + config.arrayEscape + '\\d+' + config.arrayEscape + '\\.', 'g');
function serialize(document, parentKey, maxDepth) {
if(Object.prototype.hasOwnProperty.call(excludeSubkeys, parentKey.replace(arrayRegex, '.')))
return;
for(var key in document) {
//skip over inherited properties such as string, length, etch
if(!document.hasOwnProperty(key)) {
continue;
}
var value = document[key];
if(Array.isArray(document))
key = config.arrayEscape + key + config.arrayEscape; //translate unnamed object key from {_parent_name_}.{_index_} to {_parent_name_}.arrayEscape{_index_}arrayEscape.
result[parentKey+key] = value;
//it's an object, recurse...only if we haven't reached max depth
if(isHash(value) && maxDepth > 1) {
serialize(value, parentKey+key+'.', maxDepth-1);
}
}
}
serialize(doc, '', maxDepth);
return result;
};
// convert document to key-value map, where value is always an array with types as plain strings
var analyseDocument = function(document) {
var result = {};
var arrayRegex = new RegExp('\\.' + config.arrayEscape + '\\d+' + config.arrayEscape, 'g');
for (var key in document) {
var value = document[key];
key = key.replace(arrayRegex, '.' + config.arrayEscape);
if(typeof result[key] === 'undefined') {
result[key] = {};
}
var type = varietyTypeOf(value);
result[key][type] = null;
if(config.lastValue){
if (type in {'String': true, 'Boolean': true}) {
result[key][type] = value.toString();
}else if (type in {'Number': true, 'NumberLong': true}) {
result[key][type] = value.valueOf();
}else if(type == 'ObjectId'){
result[key][type] = value.str;
}else if(type == 'Date'){
result[key][type] = new Date(value).getTime();
}else if(type.startsWith('BinData')){
result[key][type] = value.hex();
}
}
}
return result;
};
var mergeDocument = function(docResult, interimResults) {
for (var key in docResult) {
if(key in interimResults) {
var existing = interimResults[key];
for(var type in docResult[key]) {
if (type in existing.types) {
existing.types[type] = existing.types[type] + 1;
} else {
existing.types[type] = 1;
if (config.logKeysContinuously) {
log('Found new key type "' + key + '" type "' + type + '"');
}
}
}
existing.totalOccurrences = existing.totalOccurrences + 1;
} else {
var lastValue = null;
var types = {};
for (var newType in docResult[key]) {
types[newType] = 1;
lastValue = docResult[key][newType];
if (config.logKeysContinuously) {
log('Found new key type "' + key + '" type "' + newType + '"');
}
}
interimResults[key] = {'types': types,'totalOccurrences':1};
if (config.lastValue) {
interimResults[key]['lastValue'] = lastValue ? lastValue : '['+newType+']';
}
}
}
};
var convertResults = function(interimResults, documentsCount) {
var getKeys = function(obj) {
var keys = {};
for(var key in obj) {
keys[key] = obj[key];
}
return keys;
//return keys.sort();
};
var varietyResults = [];
//now convert the interimResults into the proper format
for(var key in interimResults) {
var entry = interimResults[key];
var obj = {
'_id': {'key':key},
'value': {'types':getKeys(entry.types)},
'totalOccurrences': entry.totalOccurrences,
'percentContaining': entry.totalOccurrences * 100 / documentsCount
};
if(config.lastValue){
obj.lastValue = entry.lastValue;
}
varietyResults.push(obj);
}
return varietyResults;
};
// Merge the keys and types of current object into accumulator object
var reduceDocuments = function(accumulator, object) {
var docResult = analyseDocument(serializeDoc(object, config.maxDepth, config.excludeSubkeys));
mergeDocument(docResult, accumulator);
return accumulator;
};
// We throw away keys which end in an array index, since they are not useful
// for our analysis. (We still keep the key of their parent array, though.) -JC
var arrayRegex = new RegExp('\\.' + config.arrayEscape + '$', 'g');
var filter = function(item) {
return !item._id.key.match(arrayRegex);
};
// sort desc by totalOccurrences or by key asc if occurrences equal
var comparator = function(a, b) {
var countsDiff = b.totalOccurrences - a.totalOccurrences;
return countsDiff !== 0 ? countsDiff : a._id.key.localeCompare(b._id.key);
};
var cursor = db.getCollection(config.collection).find(config.query).sort(config.sort).limit(config.limit);
var interimResults = {};
cursor.forEach(function(obj){
interimResults = reduceDocuments(interimResults, obj);
});
var varietyResults = convertResults(interimResults, cursor.size())
.filter(filter)
.sort(comparator);
if(config.persistResults) {
var resultsDB;
var resultsCollectionName = config.resultsCollection;
if (config.resultsDatabase.indexOf('/') === -1) {
// Local database; don't reconnect
resultsDB = db.getMongo().getDB(config.resultsDatabase);
} else {
// Remote database, establish new connection
resultsDB = connect(config.resultsDatabase);
}
if (config.resultsUser !== null && config.resultsPass !== null) {
resultsDB.auth(config.resultsUser, config.resultsPass);
}
// replace results collection
log('replacing results collection: '+ resultsCollectionName);
resultsDB.getCollection(resultsCollectionName).drop();
resultsDB.getCollection(resultsCollectionName).insert(varietyResults);
}
var createAsciiTable = function(results) {
var headers = ['key', 'types', 'occurrences', 'percents'];
if (config.lastValue) {
headers.push('lastValue');
}
// return the number of decimal places or 1, if the number is int (1.23=>2, 100=>1, 0.1415=>4)
var significantDigits = function(value) {
var res = value.toString().match(/^[0-9]+\.([0-9]+)$/);
return res !== null ? res[1].length : 1;
};
var maxDigits = varietyResults.map(function(value){return significantDigits(value.percentContaining);}).reduce(function(acc,val){return acc>val?acc:val;});
var rows = results.map(function(row) {
var types = [];
var typeKeys = Object.keys(row.value.types);
if (typeKeys.length > 1) {
for (var type in row.value.types) {
var typestring = type + ' (' + row.value.types[type] + ')';
types.push(typestring);
}
} else {
types = typeKeys;
}
var rawArray = [row._id.key, types, row.totalOccurrences, row.percentContaining.toFixed(Math.min(maxDigits, 20))];
if (config.lastValue && row['lastValue']) {
rawArray.push(row['lastValue']);
}
return rawArray;
});
var table = [headers, headers.map(function(){return '';})].concat(rows);
var colMaxWidth = function(arr, index) {return Math.max.apply(null, arr.map(function(row){return row[index] ? row[index].toString().length : 0;}));};
var pad = function(width, string, symbol) { return width <= string.length ? string : pad(width, isNaN(string) ? string + symbol : symbol + string, symbol); };
table = table.map(function(row, ri){
return '| ' + row.map(function(cell, i) {return pad(colMaxWidth(table, i), cell.toString(), ri === 1 ? '-' : ' ');}).join(' | ') + ' |';
});
var border = '+' + pad(table[0].length - 2, '', '-') + '+';
return [border].concat(table).concat(border).join('\n');
};
var pluginsOutput = $plugins.execute('formatResults', varietyResults);
if (pluginsOutput.length > 0) {
pluginsOutput.forEach(function(i){print(i);});
} else if(config.outputFormat === 'json') {
printjson(JSON.stringify(varietyResults));
// printjson(varietyResults); // valid formatted json output, compressed variant is printjsononeline()
} else {
print(createAsciiTable(varietyResults)); // output nice ascii table with results
}
}.bind(this)()); // end strict mode