| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| import {Filter} from '../../model/filter'; |
| import {ColumnNamesService} from '../../service/column-names.service'; |
| import {SearchRequest} from '../../model/search-request'; |
| import {SortField} from '../../model/sort-field'; |
| import {TIMESTAMP_FIELD_NAME} from '../../utils/constants'; |
| import {GroupRequest} from '../../model/group-request'; |
| import {Group} from '../../model/group'; |
| import { Injectable } from '@angular/core'; |
| |
| @Injectable() |
| export class QueryBuilder { |
| private _searchRequest = new SearchRequest(); |
| private _groupRequest = new GroupRequest(); |
| private _query = '*'; |
| private _displayQuery = this._query; |
| private _filters: Filter[] = []; |
| |
| get query(): string { |
| return this._query; |
| } |
| |
| get displayQuery(): string { |
| return this._displayQuery; |
| } |
| |
| set filters(filters: Filter[]) { |
| filters.forEach(filter => { |
| this.addOrUpdateFilter(filter) |
| }); |
| } |
| |
| get filters(): Filter[] { |
| return this._filters; |
| } |
| |
| get searchRequest(): SearchRequest { |
| this._searchRequest.query = this.generateSelect(); |
| return this._searchRequest; |
| } |
| |
| set searchRequest(value: SearchRequest) { |
| this._searchRequest = value; |
| this.setSearch(this._searchRequest.query); |
| } |
| |
| groupRequest(scoreField): GroupRequest { |
| this._groupRequest.query = this.generateSelect(); |
| this._groupRequest.scoreField = scoreField; |
| return this._groupRequest; |
| } |
| |
| setSearch(query: string) { |
| this.updateFilters(query, true); |
| this.onSearchChange(); |
| } |
| |
| clearSearch() { |
| this._filters = []; |
| this.onSearchChange(); |
| } |
| |
| addOrUpdateFilter(filter: Filter) { |
| let existingFilterIndex = -1; |
| |
| if (filter.field === TIMESTAMP_FIELD_NAME) { |
| const existingTimeRangeFilter = this.filters.find(fItem => fItem.field === TIMESTAMP_FIELD_NAME); |
| if (existingTimeRangeFilter) { |
| this.removeFilter(existingTimeRangeFilter); |
| } |
| this._filters.push(filter); |
| this.onSearchChange(); |
| return; |
| } |
| |
| let existingFilter = this._filters.find((tFilter, index) => { |
| if (filter.equals(tFilter)) { |
| existingFilterIndex = index; |
| return true; |
| } |
| return false; |
| }); |
| |
| if (existingFilter) { |
| this._filters.splice(existingFilterIndex, 1, filter); |
| } else { |
| this._filters.push(filter); |
| } |
| |
| this.onSearchChange(); |
| } |
| |
| generateSelect() { |
| let select = this._filters.map(filter => filter.getQueryString()).join(' AND '); |
| return (select.length === 0) ? '*' : select; |
| } |
| |
| generateNameForSearchRequest() { |
| let select = this._filters.map(filter => ColumnNamesService.getColumnDisplayValue(filter.field) + ':' + filter.value).join(' AND '); |
| return (select.length === 0) ? '*' : select; |
| } |
| |
| generateSelectForDisplay() { |
| let appliedFilters = []; |
| this._filters.reduce((appliedFilters, filter) => { |
| if (filter.display) { |
| appliedFilters.push(ColumnNamesService.getColumnDisplayValue(filter.field) + ':' + filter.value); |
| } |
| |
| return appliedFilters; |
| }, appliedFilters); |
| |
| let select = appliedFilters.join(' AND '); |
| return (select.length === 0) ? '*' : select; |
| } |
| |
| isTimeStampFieldPresent(): boolean { |
| return this._filters.some(filter => (filter.field === TIMESTAMP_FIELD_NAME && !isNaN(Number(filter.value)))); |
| } |
| |
| onSearchChange() { |
| this._query = this.generateSelect(); |
| this._displayQuery = this.generateSelectForDisplay(); |
| } |
| |
| removeFilter(filter: Filter) { |
| const filterIndex = this._filters.indexOf(filter); |
| if (filterIndex >= 0) { |
| this._filters.splice(filterIndex, 1); |
| this.onSearchChange(); |
| } |
| } |
| |
| setFields(fieldNames: string[]) { |
| // this.searchRequest._source = fieldNames; |
| } |
| |
| setFromAndSize(from: number, size: number) { |
| this.searchRequest.from = from; |
| this.searchRequest.size = size; |
| } |
| |
| setGroupby(groups: string[]) { |
| this._groupRequest.groups = groups.map(groupName => new Group(groupName)); |
| } |
| |
| setSort(sortBy: string, order: string) { |
| let sortField = new SortField(sortBy, order); |
| this.searchRequest.sort = [sortField]; |
| } |
| |
| private updateFilters(query: string, updateNameTransform = false) { |
| this.removeDisplayedFilters(); |
| |
| if (query && query !== '' && query !== '*') { |
| let terms = query.split(' AND '); |
| for (let term of terms) { |
| let [field, value] = this.splitTerm(term); |
| field = updateNameTransform ? ColumnNamesService.getColumnDisplayKey(field) : field; |
| value = value.trim(); |
| |
| this.addOrUpdateFilter(new Filter(field, value)); |
| } |
| } |
| } |
| |
| private splitTerm(term): string[] { |
| const lastIdxOfSeparator = term.lastIndexOf(':'); |
| return [ term.substring(0, lastIdxOfSeparator), term.substring(lastIdxOfSeparator + 1) ]; |
| } |
| |
| private removeDisplayedFilters() { |
| for (let i = this._filters.length - 1; i >= 0; i--) { |
| if (this._filters[i].display) { |
| this._filters.splice(i, 1); |
| } |
| } |
| } |
| } |