56db38ec by Adam Heath

Move most of the solr data parsing/building from Facets into Facet.

1 parent d91e8f81
...@@ -102,7 +102,7 @@ module.exports = function(grunt) { ...@@ -102,7 +102,7 @@ module.exports = function(grunt) {
102 } 102 }
103 } 103 }
104 url = parts.join('/'); 104 url = parts.join('/');
105 if (0) if (url.match(/^src\/scripts\/(.*?\/)?[^\/]+\.spec\.js$/)) { 105 if (1) if (url.match(/^src\/scripts\/(.*?\/)?[^\/]+\.spec\.js$/)) {
106 url = './.grunt/grunt-contrib-jasmine/' + url; 106 url = './.grunt/grunt-contrib-jasmine/' + url;
107 } else if (url.match(/^src\/scripts\/(.*?\/)?[^\/]+\.js$/)) { 107 } else if (url.match(/^src\/scripts\/(.*?\/)?[^\/]+\.js$/)) {
108 url = './.grunt/grunt-contrib-jasmine/' + url; 108 url = './.grunt/grunt-contrib-jasmine/' + url;
...@@ -129,8 +129,8 @@ module.exports = function(grunt) { ...@@ -129,8 +129,8 @@ module.exports = function(grunt) {
129 }; 129 };
130 130
131 templateOptions = { 131 templateOptions = {
132 coverage: 'bin/coverage/coverage.json', 132 coverage: 'dist/coverage/coverage.json',
133 report: 'bin/coverage', 133 report: 'dist/coverage',
134 replace: false, 134 replace: false,
135 template: foo, 135 template: foo,
136 templateOptions: templateOptions, 136 templateOptions: templateOptions,
......
...@@ -210,6 +210,253 @@ define(function(require) { ...@@ -210,6 +210,253 @@ define(function(require) {
210 } 210 }
211 return Facet.__super__.initialize.apply(this, arguments); 211 return Facet.__super__.initialize.apply(this, arguments);
212 }, 212 },
213 applyFacetResults: function(facetName, data, options) {
214 options = options || {};
215 var facetCounts = Util.getField(data, 'facet_counts');
216 var facetIntervals = Util.getField(facetCounts, 'facet_intervals');
217 var facetRanges = Util.getField(facetCounts, 'facet_ranges');
218 var facetFields = Util.getField(facetCounts, 'facet_fields');
219 var facetQueries = Util.getField(facetCounts, 'facet_queries');
220 var statsFields = Util.getField(data.stats, 'stats_fields');
221 function getFacetList(facetName, type) {
222 switch (type) {
223 case 'year':
224 case 'range':
225 return facetRanges[facetName] ? facetRanges[facetName].counts : null;
226 case 'interval':
227 return facetIntervals[facetName] ? facetIntervals[facetName].counts : null;
228 case 'year-field':
229 case 'field':
230 return facetFields[facetName];
231 }
232 }
233 var type = this.facetType;
234
235 var suggestions = [];
236 _.each(getFacetList('suggestions:' + facetName, type), function(value, index) {
237 if (index % 2 === 0) {
238 key = value;
239 } else if (value > 0) {
240 suggestions.push({key: key, value: value});
241 }
242 });
243 this.set('suggestions', suggestions);
244 //if (!!options.facetSuggestions && options.childFacet === facet) {
245 if (!!options.facetSuggestions) {
246 return;
247 }
248
249 var facet = this;
250 var key;
251 var list = getFacetList(facetName, type);
252 var newItems = [];
253 var items = this.get('items');
254 items.invoke('set', 'hidden', true);
255 var valueOverrides = {};
256 var excludeValues = {};
257 function recordIncludeValueIntoExclude(includeValue, key) {
258 excludeValues[includeValue] = true;
259 }
260 switch (type) {
261 case 'year-field':
262 case 'field':
263 _.each(this.bins, function(includeValues, key) {
264 var tag = facetName + ':' + key;
265 valueOverrides[key] = facetQueries[tag];
266 _.each(includeValues, recordIncludeValueIntoExclude);
267 });
268 break;
269 }
270 var addNewItem = _.bind(function addNewItem(key, value) {
271 if (valueOverrides[key] !== undefined) {
272 value = valueOverrides[key];
273 if (!value) {
274 return;
275 }
276 } else if (excludeValues[key]) {
277 return;
278 }
279 var item = items.get({id: key});
280 if (item) {
281 item.set({hidden: value === 0, value: value});
282 } else {
283 item = new Facet.Item({key: key, value: value});
284 }
285 newItems.push(item);
286 }, this);
287
288 function checkOther(set, key) {
289 if (set.indexOf(facet.other) !== -1) {
290 addNewItem(key, facetRanges[facetName][key]);
291 }
292 }
293 checkOther(['all', 'before'], 'before');
294
295 _.each(list, function(value, index) {
296 if (index % 2 === 0) {
297 key = value;
298 } else if (value > 0) {
299 addNewItem(key, value);
300 }
301 });
302 switch (type) {
303 case 'year-field':
304 case 'field':
305 _.each(this.bins, function(includeValues, key) {
306 var tag = facetName + ':' + key;
307 addNewItem(key, facetQueries[tag]);
308 });
309 break;
310 }
311 items.set(newItems, {remove: false});
312 if (this.facetStats) {
313 var thisFacetStats = statsFields[facetName];
314 this.set({minValue: thisFacetStats.min, maxValue: thisFacetStats.max});
315 }
316 },
317 getFacetFormData: function(facetName, options) {
318 options = options || {};
319 var result = {
320 'facet.field': [],
321 'facet.range': [],
322 'facet.interval': [],
323 'facet.query': [],
324 'stats.field': [],
325 fq: [],
326 };
327 var facet = this;
328 var queryField = this.queryField;
329 var facetField = this.facetField ? this.facetField : queryField;
330 var type = this.facetType;
331 var solrType = type;
332 var valueFormatter;
333 var facetOptions = {};
334 var quoteFormatter = function(value) {
335 return value.replace ? ('"' + value.replace(/"/, '\\"') + '"') : value;
336 };
337 var rangeFormatter = function(from, to) {
338 return '[' + quoteFormatter(from) + ' TO ' + quoteFormatter(to) + ']';
339 };
340 switch (type) {
341 case 'year':
342 solrType = 'range';
343 quoteFormatter = function(value) {
344 return value.toISOString();
345 };
346 valueFormatter = function(item) {
347 var key = item.get('key');
348 var fromDate, toDate;
349 if (key === 'before') {
350 return '[* TO ' + facet.rangeStart + '-1MILLISECOND]';
351 }
352 fromDate = new Date(key);
353 toDate = new Date(key);
354 toDate.setUTCFullYear(toDate.getUTCFullYear() + facet.rangeGap);
355 toDate.setTime(toDate.getTime() - 1);
356 return rangeFormatter(fromDate, toDate);
357 };
358 if (facet.other) {
359 facetOptions['facet.range.other'] = facet.other;
360 }
361 break;
362 case 'range':
363 case 'interval':
364 valueFormatter = function(item) {
365 var key = parseInt(item.get('key'));
366 return rangeFormatter(key, key + facet.rangeGap);
367 };
368 break;
369 case 'year-field':
370 solrType = 'field';
371 quoteFormatter = function(value) {
372 return new Date(value).toISOString();
373 };
374 valueFormatter = this.queryValue ? this.queryValue : function(value) {
375 return quoteFormatter(Util.getItemKeyAccessor(value));
376 };
377 _.each(this.bins, function(includeValues, key) {
378 var query = _.map(includeValues, function(includeValue, index) {
379 return queryField + ':\'' + includeValue + '\'';
380 }).join(' OR ');
381 result['facet.query'].push('{!key=' + facetName + ':' + key + ' tag=' + facetName + ':' + key + '}(' + query + ')');
382 });
383 break;
384 case 'field':
385 valueFormatter = this.queryValue ? this.queryValue : function(value) {
386 return quoteFormatter(Util.getItemKeyAccessor(value));
387 };
388 _.each(this.bins, function(includeValues, key) {
389 var query = _.map(includeValues, function(includeValue, index) {
390 return queryField + ':' + includeValue;
391 }).join(' OR ');
392 result['facet.query'].push('{!key=' + facetName + ':' + key + ' tag=' + facetName + ':' + key + '}(' + query + ')');
393 });
394 break;
395 }
396 switch (type) {
397 case 'year':
398 facetOptions['facet.range.start'] = this.rangeStart;
399 facetOptions['facet.range.end'] = this.rangeEnd;
400 facetOptions['facet.range.gap'] = '+' + this.rangeGap + 'YEAR';
401 break;
402 case 'range':
403 facetOptions['facet.range.start'] = this.rangeStart;
404 facetOptions['facet.range.end'] = this.rangeEnd;
405 facetOptions['facet.range.gap'] = this.rangeGap;
406 break;
407 case 'interval':
408 facetOptions['facet.interval.set'] = '[*,*]';
409 break;
410 }
411 var facetValues = [];
412 var queryMax = this.get('queryMax');
413 var queryMin = this.get('queryMin');
414 if (queryMax !== undefined && queryMin !== undefined) {
415 facetValues.push(rangeFormatter(queryMin, queryMax));
416 }
417 this.get('items').each(function(item, index) {
418 if (!item.get('hidden') && item.get('checked')) {
419 facetValues.push(valueFormatter(item));
420 }
421 });
422 facetOptions.key = facetName;
423 if (facetValues.length) {
424 facetOptions.ex = facetName;
425 result.fq.push('{!tag=' + facetName + '}' + facetField + ':(' + facetValues.join(' OR ') + ')');
426 } else {
427 facetOptions.tag = facetName;
428 }
429 if (!!options.facetSuggestions) {
430 var childFacet = options.childFacet;
431 if (childFacet === facet) {
432 facetOptions['facet.contains'] = this.get('query');
433 facetOptions['facet.contains.ignoreCase'] = true;
434 facetOptions['facet.mincount'] = 1;
435 }
436 }
437 var facetOptionList = [];
438 _.each(facetOptions, function(value, key) {
439 if (value !== undefined) {
440 facetOptionList.push(key + '=' + value);
441 }
442 });
443 result['facet.' + solrType].push('{!' + facetOptionList.join(' ') + '}' + queryField);
444 if (this.facetStats) {
445 result['stats.field'].push('{!' + facetOptionList.join(' ') + '}' + queryField);
446 }
447 var facetQuery = this.get('query');
448 if (facetQuery !== null && facetQuery !== '') {
449 facetOptions.key = 'suggestions:' + facetName;
450 facetOptionList = [];
451 _.each(facetOptions, function(value, key) {
452 if (value !== undefined) {
453 facetOptionList.push(key + '=' + value);
454 }
455 });
456 result['facet.' + solrType].push('{!' + facetOptionList.join(' ') + '}' + queryField);
457 }
458 return result;
459 },
213 /* 460 /*
214 toJSON: function toJSON(options) { 461 toJSON: function toJSON(options) {
215 if (!!options.facetSuggestions) { 462 if (!!options.facetSuggestions) {
......
...@@ -52,108 +52,9 @@ define(function(require) { ...@@ -52,108 +52,9 @@ define(function(require) {
52 }, 52 },
53 applyFacetResults: function(data, options) { 53 applyFacetResults: function(data, options) {
54 options = options || {}; 54 options = options || {};
55 var facetCounts = Util.getField(data, 'facet_counts');
56 var facetIntervals = Util.getField(facetCounts, 'facet_intervals');
57 var facetRanges = Util.getField(facetCounts, 'facet_ranges');
58 var facetFields = Util.getField(facetCounts, 'facet_fields');
59 var facetQueries = Util.getField(facetCounts, 'facet_queries');
60 var statsFields = Util.getField(data.stats, 'stats_fields');
61 function getFacetList(facetName, type) {
62 switch (type) {
63 case 'year':
64 case 'range':
65 return facetRanges[facetName] ? facetRanges[facetName].counts : null;
66 case 'interval':
67 return facetIntervals[facetName] ? facetIntervals[facetName].counts : null;
68 case 'year-field':
69 case 'field':
70 return facetFields[facetName];
71 }
72 }
73 _.each(this.keys(), _.bind(function(facetName) { 55 _.each(this.keys(), _.bind(function(facetName) {
74 var facet = this.get(facetName); 56 var facet = this.get(facetName);
75 var type = facet.facetType; 57 facet.applyFacetResults(facetName, data, options);
76
77 var suggestions = [];
78 _.each(getFacetList('suggestions:' + facetName, type), function(value, index) {
79 if (index % 2 === 0) {
80 key = value;
81 } else if (value > 0) {
82 suggestions.push({key: key, value: value});
83 }
84 });
85 facet.set('suggestions', suggestions);
86 //if (!!options.facetSuggestions && options.childFacet === facet) {
87 if (!!options.facetSuggestions) {
88 return;
89 }
90
91 var key;
92 var list = getFacetList(facetName, type);
93 var newItems = [];
94 var items = facet.get('items');
95 items.invoke('set', 'hidden', true);
96 var valueOverrides = {};
97 var excludeValues = {};
98 function recordIncludeValueIntoExclude(includeValue, key) {
99 excludeValues[includeValue] = true;
100 }
101 switch (type) {
102 case 'year-field':
103 case 'field':
104 _.each(facet.bins, function(includeValues, key) {
105 var tag = facetName + ':' + key;
106 valueOverrides[key] = facetQueries[tag];
107 _.each(includeValues, recordIncludeValueIntoExclude);
108 });
109 break;
110 }
111 var addNewItem = _.bind(function addNewItem(key, value) {
112 if (valueOverrides[key] !== undefined) {
113 value = valueOverrides[key];
114 if (!value) {
115 return;
116 }
117 } else if (excludeValues[key]) {
118 return;
119 }
120 var item = items.get({id: key});
121 if (item) {
122 item.set({hidden: value === 0, value: value});
123 } else {
124 item = new Facet.Item({key: key, value: value});
125 }
126 newItems.push(item);
127 }, this);
128
129 function checkOther(set, key) {
130 if (set.indexOf(facet.other) !== -1) {
131 addNewItem(key, facetRanges[facetName][key]);
132 }
133 }
134 checkOther(['all', 'before'], 'before');
135
136 _.each(list, function(value, index) {
137 if (index % 2 === 0) {
138 key = value;
139 } else if (value > 0) {
140 addNewItem(key, value);
141 }
142 });
143 switch (type) {
144 case 'year-field':
145 case 'field':
146 _.each(facet.bins, function(includeValues, key) {
147 var tag = facetName + ':' + key;
148 addNewItem(key, facetQueries[tag]);
149 });
150 break;
151 }
152 items.set(newItems, {remove: false});
153 if (facet.facetStats) {
154 var thisFacetStats = statsFields[facetName];
155 facet.set({minValue: thisFacetStats.min, maxValue: thisFacetStats.max});
156 }
157 }, this)); 58 }, this));
158 }, 59 },
159 getFacetFormData: function(options) { 60 getFacetFormData: function(options) {
...@@ -171,136 +72,17 @@ define(function(require) { ...@@ -171,136 +72,17 @@ define(function(require) {
171 }; 72 };
172 _.each(this.keys(), _.bind(function(facetName) { 73 _.each(this.keys(), _.bind(function(facetName) {
173 var facet = this.get(facetName); 74 var facet = this.get(facetName);
174 var queryField = facet.queryField; 75 var facetResult = facet.getFacetFormData(facetName, options);
175 var facetField = facet.facetField ? facet.facetField : queryField; 76 _.each([
176 var type = facet.facetType; 77 'facet.field',
177 var solrType = type; 78 'facet.range',
178 var valueFormatter; 79 'facet.interval',
179 var facetOptions = {}; 80 'facet.query',
180 var quoteFormatter = function(value) { 81 'stats.field',
181 return value.replace ? ('"' + value.replace(/"/, '\\"') + '"') : value; 82 'fq',
182 }; 83 ], function(key) {
183 var rangeFormatter = function(from, to) { 84 result[key] = result[key].concat(facetResult[key]);
184 return '[' + quoteFormatter(from) + ' TO ' + quoteFormatter(to) + ']';
185 };
186 switch (type) {
187 case 'year':
188 solrType = 'range';
189 quoteFormatter = function(value) {
190 return value.toISOString();
191 };
192 valueFormatter = function(item) {
193 var key = item.get('key');
194 var fromDate, toDate;
195 if (key === 'before') {
196 return '[* TO ' + facet.rangeStart + '-1MILLISECOND]';
197 }
198 fromDate = new Date(key);
199 toDate = new Date(key);
200 toDate.setUTCFullYear(toDate.getUTCFullYear() + facet.rangeGap);
201 toDate.setTime(toDate.getTime() - 1);
202 return rangeFormatter(fromDate, toDate);
203 };
204 if (facet.other) {
205 facetOptions['facet.range.other'] = facet.other;
206 }
207 break;
208 case 'range':
209 case 'interval':
210 valueFormatter = function(item) {
211 var key = parseInt(item.get('key'));
212 return rangeFormatter(key, key + facet.rangeGap);
213 };
214 break;
215 case 'year-field':
216 solrType = 'field';
217 quoteFormatter = function(value) {
218 return new Date(value).toISOString();
219 };
220 valueFormatter = facet.queryValue ? facet.queryValue : function(value) {
221 return quoteFormatter(Util.getItemKeyAccessor(value));
222 };
223 _.each(facet.bins, function(includeValues, key) {
224 var query = _.map(includeValues, function(includeValue, index) {
225 return queryField + ':\'' + includeValue + '\'';
226 }).join(' OR ');
227 result['facet.query'].push('{!key=' + facetName + ':' + key + ' tag=' + facetName + ':' + key + '}(' + query + ')');
228 });
229 break;
230 case 'field':
231 valueFormatter = facet.queryValue ? facet.queryValue : function(value) {
232 return quoteFormatter(Util.getItemKeyAccessor(value));
233 };
234 _.each(facet.bins, function(includeValues, key) {
235 var query = _.map(includeValues, function(includeValue, index) {
236 return queryField + ':' + includeValue;
237 }).join(' OR ');
238 result['facet.query'].push('{!key=' + facetName + ':' + key + ' tag=' + facetName + ':' + key + '}(' + query + ')');
239 });
240 break;
241 }
242 switch (type) {
243 case 'year':
244 facetOptions['facet.range.start'] = facet.rangeStart;
245 facetOptions['facet.range.end'] = facet.rangeEnd;
246 facetOptions['facet.range.gap'] = '+' + facet.rangeGap + 'YEAR';
247 break;
248 case 'range':
249 facetOptions['facet.range.start'] = facet.rangeStart;
250 facetOptions['facet.range.end'] = facet.rangeEnd;
251 facetOptions['facet.range.gap'] = facet.rangeGap;
252 break;
253 case 'interval':
254 facetOptions['facet.interval.set'] = '[*,*]';
255 break;
256 }
257 var facetValues = [];
258 var queryMax = facet.get('queryMax');
259 var queryMin = facet.get('queryMin');
260 if (queryMax !== undefined && queryMin !== undefined) {
261 facetValues.push(rangeFormatter(queryMin, queryMax));
262 }
263 facet.get('items').each(function(item, index) {
264 if (!item.get('hidden') && item.get('checked')) {
265 facetValues.push(valueFormatter(item));
266 }
267 });
268 facetOptions.key = facetName;
269 if (facetValues.length) {
270 facetOptions.ex = facetName;
271 result.fq.push('{!tag=' + facetName + '}' + facetField + ':(' + facetValues.join(' OR ') + ')');
272 } else {
273 facetOptions.tag = facetName;
274 }
275 if (!!options.facetSuggestions) {
276 var childFacet = options.childFacet;
277 if (childFacet === facet) {
278 facetOptions['facet.contains'] = facet.get('query');
279 facetOptions['facet.contains.ignoreCase'] = true;
280 facetOptions['facet.mincount'] = 1;
281 }
282 }
283 var facetOptionList = [];
284 _.each(facetOptions, function(value, key) {
285 if (value !== undefined) {
286 facetOptionList.push(key + '=' + value);
287 }
288 }); 85 });
289 result['facet.' + solrType].push('{!' + facetOptionList.join(' ') + '}' + queryField);
290 if (facet.facetStats) {
291 result['stats.field'].push('{!' + facetOptionList.join(' ') + '}' + queryField);
292 }
293 var facetQuery = facet.get('query');
294 if (facetQuery !== null && facetQuery !== '') {
295 facetOptions.key = 'suggestions:' + facetName;
296 facetOptionList = [];
297 _.each(facetOptions, function(value, key) {
298 if (value !== undefined) {
299 facetOptionList.push(key + '=' + value);
300 }
301 });
302 result['facet.' + solrType].push('{!' + facetOptionList.join(' ') + '}' + queryField);
303 }
304 }, this)); 86 }, this));
305 return result; 87 return result;
306 }, 88 },
......