diff --git a/lib/content-services/search/components/search-filter/search-filter.component.html b/lib/content-services/search/components/search-filter/search-filter.component.html
index 1bbfa7c1c6..7258f17704 100644
--- a/lib/content-services/search/components/search-filter/search-filter.component.html
+++ b/lib/content-services/search/components/search-filter/search-filter.component.html
@@ -89,7 +89,7 @@
+ (change)="onToggleBucket($event, field, bucket)">
{{ bucket.display || bucket.label }} ({{ bucket.count }})
diff --git a/lib/content-services/search/components/search-filter/search-filter.component.spec.ts b/lib/content-services/search/components/search-filter/search-filter.component.spec.ts
index 0202d555d7..7f3a1ad4ad 100644
--- a/lib/content-services/search/components/search-filter/search-filter.component.spec.ts
+++ b/lib/content-services/search/components/search-filter/search-filter.component.spec.ts
@@ -57,12 +57,13 @@ describe('SearchFilterComponent', () => {
spyOn(queryBuilder, 'addUserFacetBucket').and.callThrough();
const event: any = { checked: true };
+ const field: FacetField = { field: 'f1', label: 'f1' };
const bucket: FacetFieldBucket = { checked: false, filterQuery: 'q1', label: 'q1', count: 1 };
- component.onToggleBucket(event, bucket);
+ component.onToggleBucket(event, field, bucket);
expect(bucket.checked).toBeTruthy();
- expect(queryBuilder.addUserFacetBucket).toHaveBeenCalledWith(bucket);
+ expect(queryBuilder.addUserFacetBucket).toHaveBeenCalledWith(field, bucket);
expect(queryBuilder.update).toHaveBeenCalled();
});
@@ -71,11 +72,12 @@ describe('SearchFilterComponent', () => {
spyOn(queryBuilder, 'removeUserFacetBucket').and.callThrough();
const event: any = { checked: false };
+ const field: FacetField = { field: 'f1', label: 'f1' };
const bucket: FacetFieldBucket = { checked: true, filterQuery: 'q1', label: 'q1', count: 1 };
- component.onToggleBucket(event, bucket);
+ component.onToggleBucket(event, field, bucket);
- expect(queryBuilder.removeUserFacetBucket).toHaveBeenCalledWith(bucket);
+ expect(queryBuilder.removeUserFacetBucket).toHaveBeenCalledWith(field, bucket);
expect(queryBuilder.update).toHaveBeenCalled();
});
@@ -217,7 +219,8 @@ describe('SearchFilterComponent', () => {
it('should update query builder only when has bucket to unselect', () => {
spyOn(queryBuilder, 'update').and.stub();
- component.onToggleBucket( { checked: true }, null);
+ const field: FacetField = { field: 'f1', label: 'f1' };
+ component.onToggleBucket( { checked: true }, field, null);
expect(queryBuilder.update).not.toHaveBeenCalled();
});
diff --git a/lib/content-services/search/components/search-filter/search-filter.component.ts b/lib/content-services/search/components/search-filter/search-filter.component.ts
index 0d510606bf..fcf8178f23 100644
--- a/lib/content-services/search/components/search-filter/search-filter.component.ts
+++ b/lib/content-services/search/components/search-filter/search-filter.component.ts
@@ -130,29 +130,29 @@ export class SearchFilterComponent implements OnInit, OnDestroy {
}
}
- onToggleBucket(event: MatCheckboxChange, bucket: FacetFieldBucket) {
+ onToggleBucket(event: MatCheckboxChange, field: FacetField, bucket: FacetFieldBucket) {
if (event && bucket) {
if (event.checked) {
- this.selectFacetBucket(bucket);
+ this.selectFacetBucket(field, bucket);
} else {
- this.unselectFacetBucket(bucket);
+ this.unselectFacetBucket(field, bucket);
}
}
}
- selectFacetBucket(bucket: FacetFieldBucket) {
+ selectFacetBucket(field: FacetField, bucket: FacetFieldBucket) {
if (bucket) {
bucket.checked = true;
- this.queryBuilder.addUserFacetBucket(bucket);
+ this.queryBuilder.addUserFacetBucket(field, bucket);
this.updateSelectedBuckets();
this.queryBuilder.update();
}
}
- unselectFacetBucket(bucket: FacetFieldBucket) {
+ unselectFacetBucket(field: FacetField, bucket: FacetFieldBucket) {
if (bucket) {
bucket.checked = false;
- this.queryBuilder.removeUserFacetBucket(bucket);
+ this.queryBuilder.removeUserFacetBucket(field, bucket);
this.updateSelectedBuckets();
this.queryBuilder.update();
}
@@ -181,7 +181,7 @@ export class SearchFilterComponent implements OnInit, OnDestroy {
if (field && field.buckets) {
for (let bucket of field.buckets.items) {
bucket.checked = false;
- this.queryBuilder.removeUserFacetBucket(bucket);
+ this.queryBuilder.removeUserFacetBucket(field, bucket);
}
this.updateSelectedBuckets();
this.queryBuilder.update();
diff --git a/lib/content-services/search/search-query-builder.service.spec.ts b/lib/content-services/search/search-query-builder.service.spec.ts
index 3d27c8c691..6d26e6c496 100644
--- a/lib/content-services/search/search-query-builder.service.spec.ts
+++ b/lib/content-services/search/search-query-builder.service.spec.ts
@@ -18,6 +18,7 @@
import { SearchQueryBuilderService } from './search-query-builder.service';
import { SearchConfiguration } from './search-configuration.interface';
import { AppConfigService } from '@alfresco/adf-core';
+import { FacetField } from './facet-field.interface';
describe('SearchQueryBuilder', () => {
@@ -420,4 +421,43 @@ describe('SearchQueryBuilder', () => {
expect(compiled.query.query).toBe('(my query) AND (cm:name:test)');
});
+ it('should group facet buckets by field', () => {
+ const field1: FacetField = {
+ field: 'f1',
+ label: 'f1'
+ };
+
+ const field1buckets = [
+ { checked: true, filterQuery: 'f1-q1', label: 'f1-q1', count: 1 },
+ { checked: true, filterQuery: 'f1-q2', label: 'f1-q2', count: 1 }
+ ];
+
+ const field2: FacetField = {
+ field: 'f2',
+ label: 'f2'
+ };
+
+ const field2buckets = [
+ { checked: true, filterQuery: 'f2-q1', label: 'f2-q1', count: 1 },
+ { checked: true, filterQuery: 'f2-q2', label: 'f2-q2', count: 1 }
+ ];
+
+ const config: SearchConfiguration = {
+ categories: [
+ { id: 'cat1', enabled: true }
+ ]
+ };
+ const builder = new SearchQueryBuilderService(buildConfig(config), null);
+
+ builder.addUserFacetBucket(field1, field1buckets[0]);
+ builder.addUserFacetBucket(field1, field1buckets[1]);
+ builder.addUserFacetBucket(field2, field2buckets[0]);
+ builder.addUserFacetBucket(field2, field2buckets[1]);
+
+ const compiledQuery = builder.buildQuery();
+ const expectedResult = '(f1-q1 OR f1-q2) AND (f2-q1 OR f2-q2)';
+
+ expect(compiledQuery.query.query).toBe(expectedResult);
+ });
+
});
diff --git a/lib/content-services/search/search-query-builder.service.ts b/lib/content-services/search/search-query-builder.service.ts
index ce5b110532..471e8be22b 100644
--- a/lib/content-services/search/search-query-builder.service.ts
+++ b/lib/content-services/search/search-query-builder.service.ts
@@ -43,7 +43,7 @@ export class SearchQueryBuilderService {
sorting: Array = [];
protected userFacetQueries: FacetQuery[] = [];
- protected userFacetBuckets: FacetFieldBucket[] = [];
+ protected userFacetBuckets: { [key: string]: Array } = {};
get userQuery(): string {
return this._userQuery;
@@ -69,7 +69,7 @@ export class SearchQueryBuilderService {
this.config = JSON.parse(JSON.stringify(template));
this.categories = (this.config.categories || []).filter(category => category.enabled);
this.filterQueries = this.config.filterQueries || [];
- this.userFacetBuckets = [];
+ this.userFacetBuckets = {};
this.userFacetQueries = [];
if (this.config.sorting) {
this.sorting = this.config.sorting.defaults || [];
@@ -95,18 +95,21 @@ export class SearchQueryBuilderService {
}
}
- addUserFacetBucket(bucket: FacetFieldBucket) {
- if (bucket) {
- const existing = this.userFacetBuckets.find(facetBucket => facetBucket.label === bucket.label);
+ addUserFacetBucket(field: FacetField, bucket: FacetFieldBucket) {
+ if (field && field.field && bucket) {
+ const buckets = this.userFacetBuckets[field.field] || [];
+ const existing = buckets.find(facetBucket => facetBucket.label === bucket.label);
if (!existing) {
- this.userFacetBuckets.push(bucket);
+ buckets.push(bucket);
}
+ this.userFacetBuckets[field.field] = buckets;
}
}
- removeUserFacetBucket(bucket: FacetFieldBucket) {
- if (bucket) {
- this.userFacetBuckets = this.userFacetBuckets
+ removeUserFacetBucket(field: FacetField, bucket: FacetFieldBucket) {
+ if (field && field.field && bucket) {
+ const buckets = this.userFacetBuckets[field.field] || [];
+ this.userFacetBuckets[field.field] = buckets
.filter(facetBucket => facetBucket.label !== bucket.label);
}
}
@@ -265,11 +268,18 @@ export class SearchQueryBuilderService {
result += ` AND (${combined})`;
}
- if (this.userFacetBuckets && this.userFacetBuckets.length > 0) {
- const combined = this.userFacetBuckets
- .map(bucket => bucket.filterQuery)
- .join(' OR ');
- result += ` AND (${combined})`;
+ if (this.userFacetBuckets) {
+ Object.keys(this.userFacetBuckets).forEach(key => {
+ const subQuery = (this.userFacetBuckets[key] || [])
+ .map(bucket => bucket.filterQuery)
+ .join(' OR ');
+ if (subQuery) {
+ if (result.length > 0) {
+ result += ' AND ';
+ }
+ result += `(${subQuery})`;
+ }
+ });
}
return result;