From 5f473140fcd8dcec59b939272769f10f29fa1b4d Mon Sep 17 00:00:00 2001 From: Thomas Rueckstiess Date: Wed, 1 Mar 2017 17:08:03 +1100 Subject: [PATCH] extract field names from arrays of sub-docs --- .../indexes/lib/store/create-index-store.js | 10 +- test/fixtures/array_of_docs.fixture.json | 319 ++++++++++++++++++ test/unit/indexes.store.test.js | 13 + 3 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/array_of_docs.fixture.json diff --git a/src/internal-packages/indexes/lib/store/create-index-store.js b/src/internal-packages/indexes/lib/store/create-index-store.js index 43821210e14..d1fc0b7aa68 100644 --- a/src/internal-packages/indexes/lib/store/create-index-store.js +++ b/src/internal-packages/indexes/lib/store/create-index-store.js @@ -2,6 +2,7 @@ const Reflux = require('reflux'); const EJSON = require('mongodb-extended-json'); const Action = require('../action/index-actions'); const NamespaceStore = require('hadron-reflux-store').NamespaceStore; +const _ = require('lodash'); // const debug = require('debug')('mongodb-compass:ddl:index:store'); @@ -125,9 +126,16 @@ const CreateIndexStore = Reflux.createStore({ // recursively search sub documents for (const type of field.types) { if (type.name === 'Document') { - // append . to current path so nested documents have proper prefix + // add nested sub-fields to list of index fields possiblePaths = possiblePaths.concat(this._parseSchemaFields(type.fields, path + '.')); } + if (type.name === 'Array') { + // add nested sub-fields of document type to list of index fields + const docType = _.find(type.types, 'name', 'Document'); + if (docType) { + possiblePaths = possiblePaths.concat(this._parseSchemaFields(docType.fields, path + '.')); + } + } } } return possiblePaths; diff --git a/test/fixtures/array_of_docs.fixture.json b/test/fixtures/array_of_docs.fixture.json new file mode 100644 index 00000000000..a278beb059e --- /dev/null +++ b/test/fixtures/array_of_docs.fixture.json @@ -0,0 +1,319 @@ +{ + "fields": [ + { + "name": "_id", + "path": "_id", + "count": 4, + "types": [ + { + "name": "ObjectID", + "bsonType": "ObjectID", + "path": "_id", + "count": 4, + "values": [ + { + "$oid": "5626704c0104270098888917" + }, + { + "$oid": "5626704b0104270098888916" + }, + { + "$oid": "5626704d0104270098888918" + }, + { + "$oid": "58b66452509f926100cd8812" + } + ], + "total_count": 0, + "probability": 1, + "unique": 4, + "has_duplicates": false + } + ], + "total_count": 4, + "type": "ObjectID", + "has_duplicates": false, + "probability": 1 + }, + { + "name": "review", + "path": "review", + "count": 1, + "types": [ + { + "name": "Undefined", + "type": "Undefined", + "path": "review", + "count": 3, + "total_count": 0, + "probability": 0.75, + "unique": 1, + "has_duplicates": true + }, + { + "name": "Document", + "bsonType": "Document", + "path": "review", + "count": 1, + "fields": [ + { + "name": "_id", + "path": "review._id", + "count": 1, + "types": [ + { + "name": "Number", + "bsonType": "Number", + "path": "review._id", + "count": 1, + "values": [ + 3 + ], + "total_count": 0, + "probability": 1, + "unique": 1, + "has_duplicates": false + } + ], + "total_count": 1, + "type": "Number", + "has_duplicates": false, + "probability": 1 + }, + { + "name": "rating", + "path": "review.rating", + "count": 1, + "types": [ + { + "name": "Number", + "bsonType": "Number", + "path": "review.rating", + "count": 1, + "values": [ + 9 + ], + "total_count": 0, + "probability": 1, + "unique": 1, + "has_duplicates": false + } + ], + "total_count": 1, + "type": "Number", + "has_duplicates": false, + "probability": 1 + }, + { + "name": "text", + "path": "review.text", + "count": 1, + "types": [ + { + "name": "String", + "bsonType": "String", + "path": "review.text", + "count": 1, + "values": [ + "it was great!" + ], + "total_count": 0, + "probability": 1, + "unique": 1, + "has_duplicates": false + } + ], + "total_count": 1, + "type": "String", + "has_duplicates": false, + "probability": 1 + } + ], + "total_count": 0, + "probability": 0.25 + } + ], + "total_count": 4, + "type": [ + "Undefined", + "Document" + ], + "has_duplicates": true, + "probability": 0.25 + }, + { + "name": "reviews", + "path": "reviews", + "count": 3, + "types": [ + { + "name": "Array", + "bsonType": "Array", + "path": "reviews", + "count": 3, + "types": [ + { + "name": "Document", + "bsonType": "Document", + "path": "reviews", + "count": 6, + "fields": [ + { + "name": "_id", + "path": "reviews._id", + "count": 5, + "types": [ + { + "name": "Number", + "bsonType": "Number", + "path": "reviews._id", + "count": 5, + "values": [ + 1, + 2, + 2, + 1, + 2 + ], + "total_count": 0, + "probability": 0.8333333333333334, + "unique": 2, + "has_duplicates": true + }, + { + "name": "Undefined", + "type": "Undefined", + "path": "reviews._id", + "count": 1, + "total_count": 0, + "probability": 0.16666666666666666, + "unique": 1, + "has_duplicates": false + } + ], + "total_count": 6, + "type": [ + "Number", + "Undefined" + ], + "has_duplicates": true, + "probability": 0.8333333333333334 + }, + { + "name": "rating", + "path": "reviews.rating", + "count": 5, + "types": [ + { + "name": "Number", + "bsonType": "Number", + "path": "reviews.rating", + "count": 5, + "values": [ + 4, + 1, + 1, + 4, + 1 + ], + "total_count": 0, + "probability": 0.8333333333333334, + "unique": 2, + "has_duplicates": true + }, + { + "name": "Undefined", + "type": "Undefined", + "path": "reviews.rating", + "count": 1, + "total_count": 0, + "probability": 0.16666666666666666, + "unique": 1, + "has_duplicates": false + } + ], + "total_count": 6, + "type": [ + "Number", + "Undefined" + ], + "has_duplicates": true, + "probability": 0.8333333333333334 + }, + { + "name": "text", + "path": "reviews.text", + "count": 5, + "types": [ + { + "name": "String", + "bsonType": "String", + "path": "reviews.text", + "count": 5, + "values": [ + "great!", + "didn't like it", + "didn't like it", + "great!", + "didn't like it" + ], + "total_count": 0, + "probability": 0.8333333333333334, + "unique": 2, + "has_duplicates": true + }, + { + "name": "Undefined", + "type": "Undefined", + "path": "reviews.text", + "count": 1, + "total_count": 0, + "probability": 0.16666666666666666, + "unique": 1, + "has_duplicates": false + } + ], + "total_count": 6, + "type": [ + "String", + "Undefined" + ], + "has_duplicates": true, + "probability": 0.8333333333333334 + } + ], + "total_count": 0, + "probability": 1 + } + ], + "lengths": [ + 3, + 1, + 2 + ], + "total_count": 6, + "probability": 0.75, + "average_length": 2 + }, + { + "name": "Undefined", + "type": "Undefined", + "path": "reviews", + "count": 1, + "total_count": 0, + "probability": 0.25, + "unique": 1, + "has_duplicates": false + } + ], + "total_count": 4, + "type": [ + "Array", + "Undefined" + ], + "has_duplicates": false, + "probability": 0.75 + } + ], + "count": 4 +} diff --git a/test/unit/indexes.store.test.js b/test/unit/indexes.store.test.js index 71b3fe89fca..98f7ae2f4dd 100644 --- a/test/unit/indexes.store.test.js +++ b/test/unit/indexes.store.test.js @@ -18,6 +18,8 @@ require('../../src/app/reflux-listen-to-external-store.js'); const CreateIndexStore = require('../../src/internal-packages/indexes/lib/store/create-index-store'); const Collection = require('../../src/internal-packages/collection/lib/components/index'); +const arrayOfDocsSchema = require('../fixtures/array_of_docs.fixture.json'); + describe('CreateIndexesStore', function() { let unsubscribe; @@ -137,6 +139,17 @@ describe('CreateIndexesStore', function() { CreateIndexStore.removeIndexField(1); }); + + it('extracts top-level and nested field names from the schema', function(done) { + unsubscribe = CreateIndexStore.listen((fields, options, schemaFields) => { + expect(schemaFields).to.have.members(['reviews', 'reviews._id', + 'reviews.rating', 'reviews.text', 'review', 'review._id', + 'review.rating', 'review.text']); + unsubscribe(); + done(); + }); + CreateIndexStore.loadFields({schema: arrayOfDocsSchema}); + }); }); describe('LoadIndexesStore', () => {