Skip to content

Commit 60ee464

Browse files
authored
Merge pull request #4090 from microsoft-search/fix/3934
Fix/3934
2 parents e1ba830 + 7dfd618 commit 60ee464

File tree

3 files changed

+67
-14
lines changed

3 files changed

+67
-14
lines changed

search-parts/src/dataSources/MicrosoftSearchDataSource.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -755,16 +755,17 @@ export class MicrosoftSearchDataSource extends BaseDataSource<IMicrosoftSearchDa
755755

756756
// Build aggregation filters
757757
if (dataContext.filters.selectedFilters.length > 0) {
758-
759-
// Make sure, if we have multiple filters, at least two filters have values to avoid apply an operator ('or','and') on only one condition failing the query.
760-
if (dataContext.filters.selectedFilters.length > 1 && dataContext.filters.selectedFilters.filter(selectedFilter => selectedFilter.values.length > 0).length > 1) {
761-
const refinementString = DataFilterHelper.buildFqlRefinementString(dataContext.filters.selectedFilters, dataContext.filters.filtersConfiguration, this.moment).join(',');
762-
if (!isEmpty(refinementString)) {
763-
aggregationFilters = aggregationFilters.concat([`${dataContext.filters.filterOperator}(${refinementString})`]);
758+
if (dataContext.filters.filterOperator === 'and') {
759+
// Make sure, if we have multiple filters, at least two filters have values to avoid apply an operator ('or','and') on only one condition failing the query.
760+
const refinementStrings = DataFilterHelper.buildFqlRefinementString(dataContext.filters.selectedFilters, this.moment);
761+
if (!isEmpty(refinementStrings)) {
762+
aggregationFilters = aggregationFilters.concat(refinementStrings);
764763
}
765-
766764
} else {
767-
aggregationFilters = aggregationFilters.concat(DataFilterHelper.buildFqlRefinementString(dataContext.filters.selectedFilters, dataContext.filters.filtersConfiguration, this.moment));
765+
const refinementStrings = DataFilterHelper.buildKqlRefinementString(dataContext.filters.selectedFilters, this.moment);
766+
if (!isEmpty(refinementStrings)) {
767+
queryTemplate = refinementStrings ? `${queryTemplate} AND ${refinementStrings}` : queryTemplate;
768+
}
768769
}
769770
}
770771

search-parts/src/dataSources/SharePointSearchDataSource.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -896,13 +896,13 @@ export class SharePointSearchDataSource extends BaseDataSource<ISharePointSearch
896896

897897
// Make sure, if we have multiple filters, at least two filters have values to avoid apply an operator ('or','and') on only one condition failing the query.
898898
if (dataContext.filters.selectedFilters.length > 1 && dataContext.filters.selectedFilters.filter(selectedFilter => selectedFilter.values.length > 0).length > 1) {
899-
const refinementString = DataFilterHelper.buildFqlRefinementString(dataContext.filters.selectedFilters, dataContext.filters.filtersConfiguration, this.moment).join(',');
899+
const refinementString = DataFilterHelper.buildFqlRefinementString(dataContext.filters.selectedFilters, this.moment).join(',');
900900
if (!isEmpty(refinementString)) {
901901
refinementFilters = refinementFilters.concat([`${dataContext.filters.filterOperator}(${refinementString})`]);
902902
}
903903

904904
} else {
905-
refinementFilters = refinementFilters.concat(DataFilterHelper.buildFqlRefinementString(dataContext.filters.selectedFilters, dataContext.filters.filtersConfiguration, this.moment));
905+
refinementFilters = refinementFilters.concat(DataFilterHelper.buildFqlRefinementString(dataContext.filters.selectedFilters, this.moment));
906906
}
907907
}
908908

search-parts/src/helpers/DataFilterHelper.ts

+56-4
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,72 @@ export class DataFilterHelper {
8181
/**
8282
* Build the refinement condition in FQL format
8383
* @param selectedFilters The selected filter array
84-
* @param filtersConfiguration The current filters configuration
8584
* @param moment The moment.js instance to resolve dates
8685
* @param encodeTokens If true, encodes the taxonomy refinement tokens in UTF-8 to work with GET requests. Javascript encodes natively in UTF-16 by default.
8786
*/
88-
public static buildFqlRefinementString(selectedFilters: IDataFilter[], filtersConfiguration: IDataFilterConfiguration[], moment: any, encodeTokens?: boolean): string[] {
87+
public static buildKqlRefinementString(selectedFilters: IDataFilter[], moment: any): string {
88+
let refinementQueryConditions: string[] = [];
89+
selectedFilters.forEach(filter => {
90+
91+
const { filterName, values } = filter;
92+
93+
if (values && values.length > 0) {
94+
let startDate = null;
95+
let endDate = null;
96+
let dateOperator = null;
97+
const fieldValues = values
98+
.map(refinement => {
99+
if (moment(refinement.value, moment.ISO_8601, true).isValid()) {
100+
if (!startDate && (refinement.operator === FilterComparisonOperator.Geq || refinement.operator === FilterComparisonOperator.Gt)) {
101+
dateOperator = ">=";
102+
startDate = refinement.value;
103+
}
104+
105+
if (!endDate && (refinement.operator === FilterComparisonOperator.Lt || refinement.operator === FilterComparisonOperator.Leq)) {
106+
dateOperator = "<";
107+
endDate = refinement.value;
108+
}
109+
}
110+
else {
111+
return `${filterName}:"${refinement.name}"`;
112+
}
113+
}).filter(c => c);
114+
115+
if (startDate && endDate) {
116+
refinementQueryConditions.push(`${filter.filterName}:${startDate}..${endDate}`);
117+
} else if (startDate){
118+
refinementQueryConditions.push(`${filter.filterName}${dateOperator}${startDate}`);
119+
}
120+
else if (endDate){
121+
refinementQueryConditions.push(`${filter.filterName}${dateOperator}${endDate}`);
122+
}
123+
else {
124+
const joinedFieldValues = fieldValues.length > 1
125+
? fieldValues.join(` ${filter.operator === 'or' ? "OR" : "AND"} `)
126+
: fieldValues[0];
127+
refinementQueryConditions.push(`(${joinedFieldValues})`);
128+
}
129+
}
130+
});
131+
132+
return refinementQueryConditions.join(" OR "); // only used when building aggregation with OR between filters
133+
}
134+
135+
/**
136+
* Build the refinement condition in FQL format
137+
* @param selectedFilters The selected filter array
138+
* @param moment The moment.js instance to resolve dates
139+
* @param encodeTokens If true, encodes the taxonomy refinement tokens in UTF-8 to work with GET requests. Javascript encodes natively in UTF-16 by default.
140+
*/
141+
public static buildFqlRefinementString(selectedFilters: IDataFilter[], moment: any, encodeTokens?: boolean): string[] {
89142

90143
let refinementQueryConditions: string[] = [];
91144

92145
selectedFilters.forEach(filter => {
93146

94147
let operator: any = filter.operator;
95148

96-
// Mutli values
149+
// Multi values
97150
if (filter.values.length > 1) {
98151

99152
let startDate = null;
@@ -108,7 +161,6 @@ export class DataFilterHelper {
108161
let value = filterValue.value;
109162

110163
if (moment(value, moment.ISO_8601, true).isValid()) {
111-
112164
if (!startDate && (filterValue.operator === FilterComparisonOperator.Geq || filterValue.operator === FilterComparisonOperator.Gt)) {
113165
startDate = value;
114166
startBehaviour = filterValue.operator === FilterComparisonOperator.Gt ? "GT" : "GE";

0 commit comments

Comments
 (0)