3232
3333package org .opensearch .search .aggregations .bucket .adjacency ;
3434
35+ import org .opensearch .Version ;
3536import org .opensearch .core .ParseField ;
3637import org .opensearch .core .common .io .stream .StreamInput ;
3738import org .opensearch .core .common .io .stream .StreamOutput ;
@@ -71,7 +72,10 @@ public class AdjacencyMatrixAggregationBuilder extends AbstractAggregationBuilde
7172
7273 private static final ParseField SEPARATOR_FIELD = new ParseField ("separator" );
7374 private static final ParseField FILTERS_FIELD = new ParseField ("filters" );
75+ private static final ParseField SHOW_ONLY_INTERSECTING = new ParseField ("show_only_intersecting" );
76+
7477 private List <KeyedFilter > filters ;
78+ private boolean showOnlyIntersecting = false ;
7579 private String separator = DEFAULT_SEPARATOR ;
7680
7781 private static final ObjectParser <AdjacencyMatrixAggregationBuilder , String > PARSER = ObjectParser .fromBuilder (
@@ -81,6 +85,10 @@ public class AdjacencyMatrixAggregationBuilder extends AbstractAggregationBuilde
8185 static {
8286 PARSER .declareString (AdjacencyMatrixAggregationBuilder ::separator , SEPARATOR_FIELD );
8387 PARSER .declareNamedObjects (AdjacencyMatrixAggregationBuilder ::setFiltersAsList , KeyedFilter .PARSER , FILTERS_FIELD );
88+ PARSER .declareBoolean (
89+ AdjacencyMatrixAggregationBuilder ::setShowOnlyIntersecting ,
90+ AdjacencyMatrixAggregationBuilder .SHOW_ONLY_INTERSECTING
91+ );
8492 }
8593
8694 public static AggregationBuilder parse (XContentParser parser , String name ) throws IOException {
@@ -115,6 +123,7 @@ protected AdjacencyMatrixAggregationBuilder(
115123 super (clone , factoriesBuilder , metadata );
116124 this .filters = new ArrayList <>(clone .filters );
117125 this .separator = clone .separator ;
126+ this .showOnlyIntersecting = clone .showOnlyIntersecting ;
118127 }
119128
120129 @ Override
@@ -138,13 +147,50 @@ public AdjacencyMatrixAggregationBuilder(String name, String separator, Map<Stri
138147 setFiltersAsMap (filters );
139148 }
140149
150+ /**
151+ * @param name
152+ * the name of this aggregation
153+ * @param filters
154+ * the filters and their key to use with this aggregation.
155+ * @param showOnlyIntersecting
156+ * show only the buckets that intersection multiple documents
157+ */
158+ public AdjacencyMatrixAggregationBuilder (String name , Map <String , QueryBuilder > filters , boolean showOnlyIntersecting ) {
159+ this (name , DEFAULT_SEPARATOR , filters , showOnlyIntersecting );
160+ }
161+
162+ /**
163+ * @param name
164+ * the name of this aggregation
165+ * @param separator
166+ * the string used to separate keys in intersections buckets e.g.
167+ * & character for keyed filters A and B would return an
168+ * intersection bucket named A&B
169+ * @param filters
170+ * the filters and their key to use with this aggregation.
171+ * @param showOnlyIntersecting
172+ * show only the buckets that intersection multiple documents
173+ */
174+ public AdjacencyMatrixAggregationBuilder (
175+ String name ,
176+ String separator ,
177+ Map <String , QueryBuilder > filters ,
178+ boolean showOnlyIntersecting
179+ ) {
180+ this (name , separator , filters );
181+ this .showOnlyIntersecting = showOnlyIntersecting ;
182+ }
183+
141184 /**
142185 * Read from a stream.
143186 */
144187 public AdjacencyMatrixAggregationBuilder (StreamInput in ) throws IOException {
145188 super (in );
146189 int filtersSize = in .readVInt ();
147190 separator = in .readString ();
191+ if (in .getVersion ().onOrAfter (Version .V_3_0_0 )) {
192+ showOnlyIntersecting = in .readBoolean ();
193+ }
148194 filters = new ArrayList <>(filtersSize );
149195 for (int i = 0 ; i < filtersSize ; i ++) {
150196 filters .add (new KeyedFilter (in ));
@@ -155,6 +201,9 @@ public AdjacencyMatrixAggregationBuilder(StreamInput in) throws IOException {
155201 protected void doWriteTo (StreamOutput out ) throws IOException {
156202 out .writeVInt (filters .size ());
157203 out .writeString (separator );
204+ if (out .getVersion ().onOrAfter (Version .V_3_0_0 )) {
205+ out .writeBoolean (showOnlyIntersecting );
206+ }
158207 for (KeyedFilter keyedFilter : filters ) {
159208 keyedFilter .writeTo (out );
160209 }
@@ -185,6 +234,11 @@ private AdjacencyMatrixAggregationBuilder setFiltersAsList(List<KeyedFilter> fil
185234 return this ;
186235 }
187236
237+ public AdjacencyMatrixAggregationBuilder setShowOnlyIntersecting (boolean showOnlyIntersecting ) {
238+ this .showOnlyIntersecting = showOnlyIntersecting ;
239+ return this ;
240+ }
241+
188242 /**
189243 * Set the separator used to join pairs of bucket keys
190244 */
@@ -214,6 +268,10 @@ public Map<String, QueryBuilder> filters() {
214268 return result ;
215269 }
216270
271+ public boolean isShowOnlyIntersecting () {
272+ return showOnlyIntersecting ;
273+ }
274+
217275 @ Override
218276 protected AdjacencyMatrixAggregationBuilder doRewrite (QueryRewriteContext queryShardContext ) throws IOException {
219277 boolean modified = false ;
@@ -224,7 +282,9 @@ protected AdjacencyMatrixAggregationBuilder doRewrite(QueryRewriteContext queryS
224282 rewrittenFilters .add (new KeyedFilter (kf .key (), rewritten ));
225283 }
226284 if (modified ) {
227- return new AdjacencyMatrixAggregationBuilder (name ).separator (separator ).setFiltersAsList (rewrittenFilters );
285+ return new AdjacencyMatrixAggregationBuilder (name ).separator (separator )
286+ .setFiltersAsList (rewrittenFilters )
287+ .setShowOnlyIntersecting (showOnlyIntersecting );
228288 }
229289 return this ;
230290 }
@@ -245,7 +305,16 @@ protected AggregatorFactory doBuild(QueryShardContext queryShardContext, Aggrega
245305 + "] index level setting."
246306 );
247307 }
248- return new AdjacencyMatrixAggregatorFactory (name , filters , separator , queryShardContext , parent , subFactoriesBuilder , metadata );
308+ return new AdjacencyMatrixAggregatorFactory (
309+ name ,
310+ filters ,
311+ showOnlyIntersecting ,
312+ separator ,
313+ queryShardContext ,
314+ parent ,
315+ subFactoriesBuilder ,
316+ metadata
317+ );
249318 }
250319
251320 @ Override
@@ -257,7 +326,8 @@ public BucketCardinality bucketCardinality() {
257326 protected XContentBuilder internalXContent (XContentBuilder builder , Params params ) throws IOException {
258327 builder .startObject ();
259328 builder .field (SEPARATOR_FIELD .getPreferredName (), separator );
260- builder .startObject (AdjacencyMatrixAggregator .FILTERS_FIELD .getPreferredName ());
329+ builder .field (SHOW_ONLY_INTERSECTING .getPreferredName (), showOnlyIntersecting );
330+ builder .startObject (FILTERS_FIELD .getPreferredName ());
261331 for (KeyedFilter keyedFilter : filters ) {
262332 builder .field (keyedFilter .key (), keyedFilter .filter ());
263333 }
@@ -268,7 +338,7 @@ protected XContentBuilder internalXContent(XContentBuilder builder, Params param
268338
269339 @ Override
270340 public int hashCode () {
271- return Objects .hash (super .hashCode (), filters , separator );
341+ return Objects .hash (super .hashCode (), filters , showOnlyIntersecting , separator );
272342 }
273343
274344 @ Override
@@ -277,7 +347,9 @@ public boolean equals(Object obj) {
277347 if (obj == null || getClass () != obj .getClass ()) return false ;
278348 if (super .equals (obj ) == false ) return false ;
279349 AdjacencyMatrixAggregationBuilder other = (AdjacencyMatrixAggregationBuilder ) obj ;
280- return Objects .equals (filters , other .filters ) && Objects .equals (separator , other .separator );
350+ return Objects .equals (filters , other .filters )
351+ && Objects .equals (separator , other .separator )
352+ && Objects .equals (showOnlyIntersecting , other .showOnlyIntersecting );
281353 }
282354
283355 @ Override
0 commit comments