OpenSearch is a text-based search engine that is forked from ElasticSearch and is based on Apache Lucene.
OpenSearch provides full-text search and we can have complex query structures as well.
Let’s say we have a query where we want certain things to must match and few things can or cannot match (optional).
In such condition OpenSearch provide us a boolean query with multiple options like must
, should
, must_not
, filter
.
Using these parameters we can form the query.
Let us consider the following sample document.
{ "name": "prashant", "age": 27, "salary": 5000, "gender": "male" }
There are multiple entries of these, and we want to form a query where we want the age
to be 27, but gender
can be male
or female
. In this case, we can use a combination of must
and should
queries.
{ "query": { "bool": { "must": [ {"match": {"age": 27}} ], "should": [ {"match": {"gender": "male"}}, {"match": {"gender": "female"}}, ], "minimum_should_match": 1 } } }
Here we have also used minimum_should_match
and set it to 1, this is an optional field for should
queries that will return the result if any one of the above should
query matches.
You can use the combination and form your search query as per your requirement.
Similary, we can do the same in Java or Spring boot, using the Java SDK provided by OpenSearch.
MatchQuery mustMatchQuery1 = new MatchQuery.Builder().field("age").query(27).build(); // create a list of queries List mustQueries = new ArrayList<>(); mustQueries.add(mustMatchQuery1._toQuery()); //create multiple queries MatchQuery shouldMatchQuery1 = new MatchQuery.Builder().field("gender").query("male").build(); MatchQuery shouldMatchQuery2 = new MatchQuery.Builder().field("gender").query("female").build(); // create a list of queries List<Query> shouldQueries = new ArrayList<>(); shouldQueries.add(shouldMatchQuery1._toQuery()); shouldQueries.add(shouldMatchQuery2._toQuery()); // pass the list to boolean query for each query to must not match BoolQuery boolQuery = new BoolQuery.Builder().must(mustQueries).should(shouldQueries).minimumShouldMatch("1").build(); // perform the search SearchResponse<Object> searchResponse = client.search(s -> { s.query(boolQuery._toQuery()); return s; }, Object.class); // store the result List<Object> output = new ArrayList<>(); for (int i = 0; i < searchResponse.hits().hits().size(); i++) { output.add(searchResponse.hits().hits().get(i).source()); }