fb668f0eb564587f79e8d326f86d223298e78423
[aai/sparky-be.git] / src / main / java / org / onap / aai / sparky / search / filters / FilterQueryBuilder.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23 package org.onap.aai.sparky.search.filters;
24
25 import java.util.ArrayList;
26 import java.util.List;
27
28 import javax.json.Json;
29 import javax.json.JsonArrayBuilder;
30 import javax.json.JsonObject;
31 import javax.json.JsonObjectBuilder;
32
33 import org.onap.aai.sparky.search.filters.config.FiltersConfig;
34 import org.onap.aai.sparky.search.filters.config.UiFilterConfig;
35 import org.onap.aai.sparky.search.filters.entity.AggregationEntity;
36 import org.onap.aai.sparky.search.filters.entity.BoolQueryBuilder;
37 import org.onap.aai.sparky.search.filters.entity.FilteredAggregationQueryBuilder;
38 import org.onap.aai.sparky.search.filters.entity.MatchFilterCriteriaEntity;
39 import org.onap.aai.sparky.search.filters.entity.SearchFilter;
40
41 /**
42  * Used to generate queries against Elasticsearch for filter related queries.
43  */
44 public class FilterQueryBuilder {
45
46   private static final int EXISTING_FILTERS_LIMIT = 0;
47   private static final int SHOULD_BRANCH_LIMIT = 2;
48
49   public static JsonObject createFilteredBoolQueryObject(List<SearchFilter> searchFilters,
50       int minShouldMatch, List<String> fields) {
51
52     if (searchFilters == null || searchFilters.size() == 0) {
53       return null;
54     }
55
56     int searchFilterValueSize = 0;
57
58     BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
59
60     FiltersConfig filters = FiltersConfig.getInstance();
61
62     for (SearchFilter searchFilter : searchFilters) {
63
64       searchFilterValueSize = searchFilter.getValues().size();
65
66       /*
67        * translate the filter-id into the filter-name from the oxm data model/config file
68        */
69       UiFilterConfig filter = filters.getFilterById(searchFilter.getFilterId());
70
71       if (filter == null || filter.getFilterName() == null) {
72         // log error and continue
73       } else {
74
75         String fieldName = filter.getDataSource().getFieldName();
76         if (!fields.contains(fieldName)) {
77           fields.add(fieldName);
78         }
79
80         if (searchFilterValueSize >= SHOULD_BRANCH_LIMIT) {
81           // Add should branches
82           for (String filterValue : searchFilter.getValues()) {
83             boolQueryBuilder.addShouldFilter(new MatchFilterCriteriaEntity(fieldName, filterValue));
84           }
85
86         } else if (searchFilterValueSize > EXISTING_FILTERS_LIMIT) {
87           // Add must branch
88           for (String filterValue : searchFilter.getValues()) {
89             boolQueryBuilder.addMustFilter(new MatchFilterCriteriaEntity(fieldName, filterValue));
90           }
91         }
92       }
93     }
94
95     boolQueryBuilder.setMinShouldMatch(minShouldMatch);
96
97     return boolQueryBuilder.getJsonObject();
98   }
99
100   public static JsonObject createAggregationQueryArray(List<SearchFilter> searchFilters) {
101
102     if (searchFilters == null || searchFilters.size() == 0) {
103       // log error
104       return null;
105     }
106
107     FilteredAggregationQueryBuilder aggQueryBuilder = new FilteredAggregationQueryBuilder();
108
109     FiltersConfig filters = FiltersConfig.getInstance();
110
111     for (SearchFilter searchFilter : searchFilters) {
112
113       /*
114        * translate the filter-id into the filter-name from the oxm data model/config file
115        */
116       UiFilterConfig filter = filters.getFilterById(searchFilter.getFilterId());
117
118       if (filter == null || filter.getFilterName() == null) {
119         // log error and continue
120       } else {
121         String fieldName = filter.getDataSource().getFieldName();
122         aggQueryBuilder.addAggregationEntity(new AggregationEntity(fieldName, fieldName, 0));
123       }
124
125     }
126
127     return aggQueryBuilder.getJsonObject();
128   }
129
130   public static JsonObject createCombinedBoolAndAggQuery(List<SearchFilter> searchFilters,
131       int minShouldMatch) {
132     JsonObjectBuilder wrappedQueryBuilder = Json.createObjectBuilder();
133     if (searchFilters != null) {
134       List<String> fields = new ArrayList<String>();
135       JsonObject boolQuery = createFilteredBoolQueryObject(searchFilters, minShouldMatch, fields);
136       JsonObject aggQuery = createAggregationQueryArray(searchFilters);
137
138       if (boolQuery != null) {
139         wrappedQueryBuilder.add("size", 0);
140
141         JsonArrayBuilder filedsArrayBuilder = Json.createBuilderFactory(null).createArrayBuilder(); // TODO
142                                                                                                     // ->
143                                                                                                     // Should
144                                                                                                     // we
145                                                                                                     // use
146                                                                                                     // a
147                                                                                                     // class
148                                                                                                     // instance
149                                                                                                     // factory?
150         for (String field : fields) {
151           filedsArrayBuilder.add(field);
152         }
153         wrappedQueryBuilder.add("fields", filedsArrayBuilder.build());
154
155         wrappedQueryBuilder.add("query", boolQuery);
156       }
157
158       if (aggQuery != null) {
159         wrappedQueryBuilder.add("aggs", aggQuery);
160       }
161     }
162     return wrappedQueryBuilder.build();
163   }
164
165   public static JsonObject createFilterValueQueryObject(String fieldValue) {
166     JsonObjectBuilder jsonBuilder = Json.createObjectBuilder();
167     jsonBuilder.add("size", "0"); // avoid source data
168     buildZeroTermSummaryQuery(jsonBuilder, fieldValue);
169
170     return jsonBuilder.build();
171   }
172
173   public static JsonObject createNestedFilterValueQueryObject(String fieldValue,
174       String pathToField) {
175     JsonObjectBuilder jsonBuilder = Json.createObjectBuilder();
176     jsonBuilder.add("size", "0"); // avoid source data
177     generateNestedAggregations(jsonBuilder, fieldValue, pathToField);
178
179     return jsonBuilder.build();
180   }
181
182   public static void buildZeroTermSummaryQuery(JsonObjectBuilder jsonBuilder, String fieldValue) {
183     JsonObjectBuilder aggsBlobBuilder = Json.createObjectBuilder();
184     getSummaryAggsBlob(aggsBlobBuilder, fieldValue, 0);
185     jsonBuilder.add("aggs", aggsBlobBuilder.build());
186   }
187
188   public static void getSummaryAggsBlob(JsonObjectBuilder aggsBlobBuilder, String fieldValue,
189       int resultSize) {
190     JsonObjectBuilder fieldBuilder =
191         Json.createObjectBuilder().add("field", fieldValue).add("size", resultSize);
192     JsonObject aggsFieldBlob = fieldBuilder.build();
193     JsonObjectBuilder defaultBlobBuilder = Json.createObjectBuilder().add("terms", aggsFieldBlob);
194     JsonObject defaultBlob = defaultBlobBuilder.build();
195     aggsBlobBuilder.add("default", defaultBlob);
196   }
197
198   public static void addNestedSummaryAggsBlob(JsonObjectBuilder nestedAggsBuilder,
199       String containerValue, String fieldValue, int resultSize) {
200     JsonObjectBuilder fieldBuilder = Json.createObjectBuilder()
201         .add("field", containerValue + "." + fieldValue).add("size", resultSize);
202     JsonObject aggsFieldObject = fieldBuilder.build();
203
204     JsonObjectBuilder termBuilder = Json.createObjectBuilder().add("terms", aggsFieldObject);
205     JsonObject termObject = termBuilder.build();
206
207     JsonObjectBuilder namedAggsBuilder = Json.createObjectBuilder().add(fieldValue, termObject);
208     JsonObject namedAggsObject = namedAggsBuilder.build();
209
210     nestedAggsBuilder.add("aggs", namedAggsObject);
211   }
212
213   public static void generateNestedAggregations(JsonObjectBuilder jsonBuilder, String fieldValue,
214       String pathToField) {
215     JsonObjectBuilder nestedAggsBuilder = Json.createObjectBuilder();
216
217     JsonObjectBuilder pathObjectBuilder = Json.createObjectBuilder().add("path", pathToField);
218     JsonObject nestedPathObject = pathObjectBuilder.build();
219
220     JsonObjectBuilder nestedObjectBuilder =
221         Json.createObjectBuilder().add("nested", nestedPathObject);
222
223     addNestedSummaryAggsBlob(nestedObjectBuilder, pathToField, fieldValue, 0);
224
225     JsonObject nestedObject = nestedObjectBuilder.build();
226     nestedAggsBuilder.add(pathToField, nestedObject);
227
228     jsonBuilder.add("aggs", nestedAggsBuilder.build());
229   }
230 }