Skip to content

Commit f1bb3cd

Browse files
durranimlucas
authored andcommitted
Backport COMPASS-703 extract field names from arrays of sub-docs (#809) (#810)
1 parent 36d9373 commit f1bb3cd

File tree

3 files changed

+341
-1
lines changed

3 files changed

+341
-1
lines changed

src/internal-packages/indexes/lib/store/create-index-store.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const Reflux = require('reflux');
22
const EJSON = require('mongodb-extended-json');
33
const Action = require('../action/index-actions');
44
const NamespaceStore = require('hadron-reflux-store').NamespaceStore;
5+
const _ = require('lodash');
56

67
// const debug = require('debug')('mongodb-compass:ddl:index:store');
78

@@ -125,9 +126,16 @@ const CreateIndexStore = Reflux.createStore({
125126
// recursively search sub documents
126127
for (const type of field.types) {
127128
if (type.name === 'Document') {
128-
// append . to current path so nested documents have proper prefix
129+
// add nested sub-fields to list of index fields
129130
possiblePaths = possiblePaths.concat(this._parseSchemaFields(type.fields, path + '.'));
130131
}
132+
if (type.name === 'Array') {
133+
// add nested sub-fields of document type to list of index fields
134+
const docType = _.find(type.types, 'name', 'Document');
135+
if (docType) {
136+
possiblePaths = possiblePaths.concat(this._parseSchemaFields(docType.fields, path + '.'));
137+
}
138+
}
131139
}
132140
}
133141
return possiblePaths;
Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
{
2+
"fields": [
3+
{
4+
"name": "_id",
5+
"path": "_id",
6+
"count": 4,
7+
"types": [
8+
{
9+
"name": "ObjectID",
10+
"bsonType": "ObjectID",
11+
"path": "_id",
12+
"count": 4,
13+
"values": [
14+
{
15+
"$oid": "5626704c0104270098888917"
16+
},
17+
{
18+
"$oid": "5626704b0104270098888916"
19+
},
20+
{
21+
"$oid": "5626704d0104270098888918"
22+
},
23+
{
24+
"$oid": "58b66452509f926100cd8812"
25+
}
26+
],
27+
"total_count": 0,
28+
"probability": 1,
29+
"unique": 4,
30+
"has_duplicates": false
31+
}
32+
],
33+
"total_count": 4,
34+
"type": "ObjectID",
35+
"has_duplicates": false,
36+
"probability": 1
37+
},
38+
{
39+
"name": "review",
40+
"path": "review",
41+
"count": 1,
42+
"types": [
43+
{
44+
"name": "Undefined",
45+
"type": "Undefined",
46+
"path": "review",
47+
"count": 3,
48+
"total_count": 0,
49+
"probability": 0.75,
50+
"unique": 1,
51+
"has_duplicates": true
52+
},
53+
{
54+
"name": "Document",
55+
"bsonType": "Document",
56+
"path": "review",
57+
"count": 1,
58+
"fields": [
59+
{
60+
"name": "_id",
61+
"path": "review._id",
62+
"count": 1,
63+
"types": [
64+
{
65+
"name": "Number",
66+
"bsonType": "Number",
67+
"path": "review._id",
68+
"count": 1,
69+
"values": [
70+
3
71+
],
72+
"total_count": 0,
73+
"probability": 1,
74+
"unique": 1,
75+
"has_duplicates": false
76+
}
77+
],
78+
"total_count": 1,
79+
"type": "Number",
80+
"has_duplicates": false,
81+
"probability": 1
82+
},
83+
{
84+
"name": "rating",
85+
"path": "review.rating",
86+
"count": 1,
87+
"types": [
88+
{
89+
"name": "Number",
90+
"bsonType": "Number",
91+
"path": "review.rating",
92+
"count": 1,
93+
"values": [
94+
9
95+
],
96+
"total_count": 0,
97+
"probability": 1,
98+
"unique": 1,
99+
"has_duplicates": false
100+
}
101+
],
102+
"total_count": 1,
103+
"type": "Number",
104+
"has_duplicates": false,
105+
"probability": 1
106+
},
107+
{
108+
"name": "text",
109+
"path": "review.text",
110+
"count": 1,
111+
"types": [
112+
{
113+
"name": "String",
114+
"bsonType": "String",
115+
"path": "review.text",
116+
"count": 1,
117+
"values": [
118+
"it was great!"
119+
],
120+
"total_count": 0,
121+
"probability": 1,
122+
"unique": 1,
123+
"has_duplicates": false
124+
}
125+
],
126+
"total_count": 1,
127+
"type": "String",
128+
"has_duplicates": false,
129+
"probability": 1
130+
}
131+
],
132+
"total_count": 0,
133+
"probability": 0.25
134+
}
135+
],
136+
"total_count": 4,
137+
"type": [
138+
"Undefined",
139+
"Document"
140+
],
141+
"has_duplicates": true,
142+
"probability": 0.25
143+
},
144+
{
145+
"name": "reviews",
146+
"path": "reviews",
147+
"count": 3,
148+
"types": [
149+
{
150+
"name": "Array",
151+
"bsonType": "Array",
152+
"path": "reviews",
153+
"count": 3,
154+
"types": [
155+
{
156+
"name": "Document",
157+
"bsonType": "Document",
158+
"path": "reviews",
159+
"count": 6,
160+
"fields": [
161+
{
162+
"name": "_id",
163+
"path": "reviews._id",
164+
"count": 5,
165+
"types": [
166+
{
167+
"name": "Number",
168+
"bsonType": "Number",
169+
"path": "reviews._id",
170+
"count": 5,
171+
"values": [
172+
1,
173+
2,
174+
2,
175+
1,
176+
2
177+
],
178+
"total_count": 0,
179+
"probability": 0.8333333333333334,
180+
"unique": 2,
181+
"has_duplicates": true
182+
},
183+
{
184+
"name": "Undefined",
185+
"type": "Undefined",
186+
"path": "reviews._id",
187+
"count": 1,
188+
"total_count": 0,
189+
"probability": 0.16666666666666666,
190+
"unique": 1,
191+
"has_duplicates": false
192+
}
193+
],
194+
"total_count": 6,
195+
"type": [
196+
"Number",
197+
"Undefined"
198+
],
199+
"has_duplicates": true,
200+
"probability": 0.8333333333333334
201+
},
202+
{
203+
"name": "rating",
204+
"path": "reviews.rating",
205+
"count": 5,
206+
"types": [
207+
{
208+
"name": "Number",
209+
"bsonType": "Number",
210+
"path": "reviews.rating",
211+
"count": 5,
212+
"values": [
213+
4,
214+
1,
215+
1,
216+
4,
217+
1
218+
],
219+
"total_count": 0,
220+
"probability": 0.8333333333333334,
221+
"unique": 2,
222+
"has_duplicates": true
223+
},
224+
{
225+
"name": "Undefined",
226+
"type": "Undefined",
227+
"path": "reviews.rating",
228+
"count": 1,
229+
"total_count": 0,
230+
"probability": 0.16666666666666666,
231+
"unique": 1,
232+
"has_duplicates": false
233+
}
234+
],
235+
"total_count": 6,
236+
"type": [
237+
"Number",
238+
"Undefined"
239+
],
240+
"has_duplicates": true,
241+
"probability": 0.8333333333333334
242+
},
243+
{
244+
"name": "text",
245+
"path": "reviews.text",
246+
"count": 5,
247+
"types": [
248+
{
249+
"name": "String",
250+
"bsonType": "String",
251+
"path": "reviews.text",
252+
"count": 5,
253+
"values": [
254+
"great!",
255+
"didn't like it",
256+
"didn't like it",
257+
"great!",
258+
"didn't like it"
259+
],
260+
"total_count": 0,
261+
"probability": 0.8333333333333334,
262+
"unique": 2,
263+
"has_duplicates": true
264+
},
265+
{
266+
"name": "Undefined",
267+
"type": "Undefined",
268+
"path": "reviews.text",
269+
"count": 1,
270+
"total_count": 0,
271+
"probability": 0.16666666666666666,
272+
"unique": 1,
273+
"has_duplicates": false
274+
}
275+
],
276+
"total_count": 6,
277+
"type": [
278+
"String",
279+
"Undefined"
280+
],
281+
"has_duplicates": true,
282+
"probability": 0.8333333333333334
283+
}
284+
],
285+
"total_count": 0,
286+
"probability": 1
287+
}
288+
],
289+
"lengths": [
290+
3,
291+
1,
292+
2
293+
],
294+
"total_count": 6,
295+
"probability": 0.75,
296+
"average_length": 2
297+
},
298+
{
299+
"name": "Undefined",
300+
"type": "Undefined",
301+
"path": "reviews",
302+
"count": 1,
303+
"total_count": 0,
304+
"probability": 0.25,
305+
"unique": 1,
306+
"has_duplicates": false
307+
}
308+
],
309+
"total_count": 4,
310+
"type": [
311+
"Array",
312+
"Undefined"
313+
],
314+
"has_duplicates": false,
315+
"probability": 0.75
316+
}
317+
],
318+
"count": 4
319+
}

test/unit/indexes.store.test.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ require('../../src/app/reflux-listen-to-external-store.js');
1818
const CreateIndexStore = require('../../src/internal-packages/indexes/lib/store/create-index-store');
1919
const Collection = require('../../src/internal-packages/collection/lib/components/index');
2020

21+
const arrayOfDocsSchema = require('../fixtures/array_of_docs.fixture.json');
22+
2123
describe('CreateIndexesStore', function() {
2224
let unsubscribe;
2325

@@ -137,6 +139,17 @@ describe('CreateIndexesStore', function() {
137139

138140
CreateIndexStore.removeIndexField(1);
139141
});
142+
143+
it('extracts top-level and nested field names from the schema', function(done) {
144+
unsubscribe = CreateIndexStore.listen((fields, options, schemaFields) => {
145+
expect(schemaFields).to.have.members(['reviews', 'reviews._id',
146+
'reviews.rating', 'reviews.text', 'review', 'review._id',
147+
'review.rating', 'review.text']);
148+
unsubscribe();
149+
done();
150+
});
151+
CreateIndexStore.loadFields({schema: arrayOfDocsSchema});
152+
});
140153
});
141154

142155
describe('LoadIndexesStore', () => {

0 commit comments

Comments
 (0)