Skip to content

Commit

Permalink
Adding guides, samples and fixing tests
Browse files Browse the repository at this point in the history
Signed-off-by: Vacha Shah <vachshah@amazon.com>
  • Loading branch information
VachaShah committed May 6, 2024
1 parent 7767c2c commit a65cde7
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This section is for maintaining a changelog for all breaking changes for the cli
### Fixed
- Fix version and build ([#254](https://github.com/opensearch-project/opensearch-java/pull/254))
- Fix integer overflow for variables in indices stats response ([#960](https://github.com/opensearch-project/opensearch-java/pull/960))
- Fix composite aggregations for search requests ([#967](https://github.com/opensearch-project/opensearch-java/pull/967))


### Security
Expand Down
22 changes: 22 additions & 0 deletions guides/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
- [Basic Search](#basic-search)
- [Get raw JSON results](#get-raw-json-results)
- [Search documents using a match query](#search-documents-using-a-match-query)
- [Search documents using a hybrid query](#search-documents-using-a-hybrid-query)
- [Search documents using suggesters](#search-documents-using-suggesters)
- [Using completion suggester](#using-completion-suggester)
- [Using term suggester](#using-term-suggester)
- [Using phrase suggester](#using-phrase-suggester)
- [Aggregations](#aggregations)
- [Composite Aggregations](#composite-aggregations)

# Search

Expand Down Expand Up @@ -299,4 +301,24 @@ for (Map.Entry<String, Aggregate> entry : searchResponse.aggregations().entrySet
}
```

#### Composite Aggregations

```java
final Map<String, CompositeAggregationSource> comAggrSrcMap = new HashMap<>();
CompositeAggregationSource compositeAggregationSource1 = new CompositeAggregationSource.Builder().terms(
termsAggrBuilder -> termsAggrBuilder.field("title.keyword").missingBucket(false).order(SortOrder.Asc)
).build();
comAggrSrcMap.put("titles", compositeAggregationSource1);

CompositeAggregation compAgg = new CompositeAggregation.Builder().sources(comAggrSrcMap).build();
Aggregation aggregation = new Aggregation.Builder().composite(compAgg).build();

SearchRequest request = SearchRequest.of(r -> r.index(indexName).query(q -> q.match(m -> m.field("title").query(FieldValue.of("Document 1")))).aggregations("my_buckets", aggregation));
SearchResponse<IndexData> response = client.search(request, IndexData.class);
for (Map.Entry<String, Aggregate> entry : response.aggregations().entrySet()) {
LOGGER.info("Agg - {}", entry.getKey());
entry.getValue().composite().buckets().array().forEach(b -> LOGGER.info("{} : {}", b.key(), b.docCount()));
}
```

You can find a working sample of the above code in [Search.java](../samples/src/main/java/org/opensearch/client/samples/Search.java).
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,11 @@
import org.opensearch.client.json.ObjectDeserializer;
import org.opensearch.client.opensearch._types.Script;
import org.opensearch.client.opensearch._types.SortOrder;
import org.opensearch.client.util.ApiTypeHelper;
import org.opensearch.client.util.ObjectBuilder;
import org.opensearch.client.util.ObjectBuilderBase;

public abstract class CompositeValuesSource implements JsonpSerializable {

private final String name;

@Nullable
private final String field;

Expand All @@ -39,8 +36,6 @@ public abstract class CompositeValuesSource implements JsonpSerializable {
private String format;

protected CompositeValuesSource(AbstractBuilder<?> builder) {
this.name = ApiTypeHelper.requireNonNull(builder.name, this, "name");
;
this.field = builder.field;
this.script = builder.script;
this.valueType = builder.valueType;
Expand All @@ -50,13 +45,6 @@ protected CompositeValuesSource(AbstractBuilder<?> builder) {
this.format = builder.format;
}

/**
* API name: {@code name}
*/
public final String name() {
return this.name;
}

/**
* API name: {@code field}
*/
Expand Down Expand Up @@ -123,9 +111,6 @@ public void serialize(JsonGenerator generator, JsonpMapper mapper) {
}

protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
generator.writeKey(this.name);
generator.write(this.name);

if (this.field != null) {
generator.writeKey("field");
generator.write(this.field);
Expand Down Expand Up @@ -165,8 +150,6 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {

protected abstract static class AbstractBuilder<BuilderT extends AbstractBuilder<BuilderT>> extends ObjectBuilderBase {

private String name;

@Nullable
private String field;

Expand All @@ -188,14 +171,6 @@ protected abstract static class AbstractBuilder<BuilderT extends AbstractBuilder
@Nullable
private String format;

/**
* Required - API name: {@code name}
*/
public final BuilderT name(String name) {
this.name = name;
return self();
}

/**
* API name: {@code field}
*/
Expand Down Expand Up @@ -265,7 +240,6 @@ public final BuilderT format(@Nullable String format) {
protected static <BuilderT extends AbstractBuilder<BuilderT>> void setupCompositeValuesSourceDeserializer(
ObjectDeserializer<BuilderT> op
) {
op.add(AbstractBuilder::name, JsonpDeserializer.stringDeserializer(), "name");
op.add(AbstractBuilder::field, JsonpDeserializer.stringDeserializer(), "field");
op.add(AbstractBuilder::script, Script._DESERIALIZER, "script");
op.add(AbstractBuilder::valueType, ValueType._DESERIALIZER, "value_type");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.junit.Test;
import org.opensearch.Version;
import org.opensearch.client.opensearch._types.FieldValue;
import org.opensearch.client.opensearch._types.SortOrder;
import org.opensearch.client.opensearch._types.aggregations.Aggregation;
import org.opensearch.client.opensearch._types.aggregations.AggregationBuilders;
import org.opensearch.client.opensearch._types.aggregations.CompositeAggregation;
import org.opensearch.client.opensearch._types.aggregations.CompositeAggregationSource;
import org.opensearch.client.opensearch._types.aggregations.CompositeBucket;
import org.opensearch.client.opensearch._types.mapping.Property;
import org.opensearch.client.opensearch._types.query_dsl.BoolQuery;
import org.opensearch.client.opensearch._types.query_dsl.MatchQuery;
import org.opensearch.client.opensearch._types.query_dsl.Query;
import org.opensearch.client.opensearch._types.query_dsl.QueryBuilders;
Expand Down Expand Up @@ -71,22 +73,46 @@ public void shouldReturnSearchResultsWithCompositeAgg() throws Exception {
final String index = "search_request";
createIndex(index);

BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool();
final Query query = Query.of(
q -> q.bool(
builder -> builder.filter(filter -> filter.term(TermQuery.of(term -> term.field("size").value(FieldValue.of("huge")))))
)
);

final Map<String, CompositeAggregationSource> comAggrSrcMap = new HashMap<>();
CompositeAggregationSource compositeAggregationSource1 = new CompositeAggregationSource.Builder().terms(
t -> t.field("size.keyword").order(SortOrder.Desc).name("terms").missingBucket(true)
termsAggrBuilder -> termsAggrBuilder.field("quantity").missingBucket(false).order(SortOrder.Asc)
).build();
comAggrSrcMap.put("quantity", compositeAggregationSource1);

Aggregation aggregation = new Aggregation.Builder().composite(
AggregationBuilders.composite().sources(Map.of("composite", compositeAggregationSource1)).size(0).build()
).build();
CompositeAggregation compAgg = new CompositeAggregation.Builder().sources(comAggrSrcMap).build();

final SearchRequest request = SearchRequest.of(
r -> r.index(index).query(boolQueryBuilder.build().toQuery()).aggregations("composite", aggregation).size(1000)
);
Aggregation aggregation = new Aggregation.Builder().composite(compAgg).build();

final SearchRequest request = SearchRequest.of(r -> r.index(index).query(query).aggregations("my_buckets", aggregation));

final SearchResponse<ShopItem> response = javaClient().search(request, ShopItem.class);
assertEquals(response.hits().hits().size(), 8);
assertEquals(response.hits().hits().size(), 2);
for (Map.Entry<String, Aggregation> entry : response.aggregations().entrySet()) {
CompositeAggregation compositeAggregation = entry.getValue().composite();
assertEquals(2, compositeAggregation.buckets().size());
assertEquals(1, Integer.parseInt(compositeAggregation.buckets().get(0).key().get("quantity").toString()));
assertEquals(1, compositeAggregation.buckets().get(0).docCount());
assertEquals(2, Integer.parseInt(compositeAggregation.buckets().get(1).key().get("quantity").toString()));
assertEquals(1, compositeAggregation.buckets().get(1).docCount());
}
List<CompositeBucket> buckets = response.aggregations()
.entrySet()
.stream()
.filter(e -> e.getKey().equals("my_buckets"))
.map(e -> e.getValue().composite().buckets().array())
.flatMap(List::stream)
.collect(Collectors.toList());
assertEquals(2, buckets.size());
assertEquals(1, Integer.parseInt(buckets.get(0).key().get("quantity").toString()));
assertEquals(1, buckets.get(0).docCount());
assertEquals(2, Integer.parseInt(buckets.get(1).key().get("quantity").toString()));
assertEquals(1, buckets.get(1).docCount());
}

@Test
Expand Down
25 changes: 25 additions & 0 deletions samples/src/main/java/org/opensearch/client/samples/Search.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.opensearch._types.FieldValue;
import org.opensearch.client.opensearch._types.Refresh;
import org.opensearch.client.opensearch._types.SortOrder;
import org.opensearch.client.opensearch._types.aggregations.Aggregate;
import org.opensearch.client.opensearch._types.aggregations.Aggregation;
import org.opensearch.client.opensearch._types.aggregations.CompositeAggregation;
import org.opensearch.client.opensearch._types.aggregations.CompositeAggregationSource;
import org.opensearch.client.opensearch._types.analysis.Analyzer;
import org.opensearch.client.opensearch._types.analysis.CustomAnalyzer;
import org.opensearch.client.opensearch._types.analysis.ShingleTokenFilter;
Expand Down Expand Up @@ -106,6 +110,27 @@ public static void main(String[] args) {
entry.getValue().sterms().buckets().array().forEach(b -> LOGGER.info("{} : {}", b.key(), b.docCount()));
}

// Custom Aggregations
final Map<String, CompositeAggregationSource> comAggrSrcMap = new HashMap<>();
CompositeAggregationSource compositeAggregationSource1 = new CompositeAggregationSource.Builder().terms(
termsAggrBuilder -> termsAggrBuilder.field("title.keyword").missingBucket(false).order(SortOrder.Asc)
).build();
comAggrSrcMap.put("titles", compositeAggregationSource1);

CompositeAggregation compAgg = new CompositeAggregation.Builder().sources(comAggrSrcMap).build();
Aggregation aggregation = new Aggregation.Builder().composite(compAgg).build();

SearchRequest request = SearchRequest.of(
r -> r.index(indexName)
.query(q -> q.match(m -> m.field("title").query(FieldValue.of("Document 1"))))
.aggregations("my_buckets", aggregation)
);
SearchResponse<IndexData> response = client.search(request, IndexData.class);
for (Map.Entry<String, Aggregate> entry : response.aggregations().entrySet()) {
LOGGER.info("Agg - {}", entry.getKey());
entry.getValue().composite().buckets().array().forEach(b -> LOGGER.info("{} : {}", b.key(), b.docCount()));
}

// HybridSearch
Query searchQuery = Query.of(
h -> h.hybrid(
Expand Down

0 comments on commit a65cde7

Please sign in to comment.