I'm trying to perform the Elastic equivalent to the following in SQL:
select * from Pets
where type is 'cat'
and age > 10
and name in ("Barry", "Oscar", .....)
I have the following Java code:
SearchRequest searchRequest = new SearchRequest(elasticIndexName);
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(QueryBuilders.termQuery("type", "cat"));
queryBuilder.must(QueryBuilders.rangeQuery("age").from("10"));
queryBuilder.must(QueryBuilders.termQuery("name", "Oscar"));
queryBuilder.must(QueryBuilders.termQuery("name", "Barry"));
But, if I understand correctly, the last two "must" statements are contradicting each other.
I tried to use the "should" term but it seems to bring all the cat names.
You're almost there, you need to do it like this (i.e. use a terms query):
SearchRequest searchRequest = new SearchRequest(elasticIndexName);
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(QueryBuilders.termQuery("type", "cat"));
queryBuilder.must(QueryBuilders.rangeQuery("age").from("10"));
queryBuilder.must(QueryBuilders.termsQuery("name", "Oscar", "Barry"));
instead of the term query, I think you should try this, it'll help you to get the best results.
BoolQueryBuilder boolQueryBuilder = boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("type", cat));
boolQueryBuilder.must(QueryBuilders.rangeQuery("age").gt(10));
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(String.join(" ", Arrays.asList("Barry", "Oscar"), name).type(Type.BEST_FIELDS));
Related
I'm newbie to opensearch.
I'm working on utilizing the OpenSearch's Java SDK.
I'know that this contain two java class for client:
OpenSearchClient
RestHighLevelClient
I know that RestHighLevelClient has been deprecated in elasticsearch 7.x, and conversion between camel case and snake case is not possible.
For this reason, while using the OpenSearchClient, I found that the wrapper query does not exist for the OpenSearchClient.
So, What I want to ask is:
How to do wrapper query using OpenSearchClient?
The current logic with RestHighLevelClient is:
String query = "{\"term\":{\"name.keyword\":{\"value\":\"bob\"}}}"
BoolQueryBuilder queryBuilder = new BoolQueryBuilder()
.must(new WrapperQueryBuilder(query));
RestClientBuilder builder = getRestClientBuilder();
SearchResponse searchResponse;
try (RestHighLevelClient highLevelClient = new RestHighLevelClient(builder)) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
.query(queryBuilder).from(0).size(10);
SearchRequest searchRequest = Requests.searchRequest("my_index")
.source(searchSourceBuilder);
searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
}
Thanks for sharing your knowledge.
I am looking to build a query filter in java for Elsaticsearch 5.2 to match any of the keywords wether they are author supplied or system generated. I am trying to do a wild card path but it does not return any results. I am using standard dynamic mapping in Elasticsearch.
{
"content": {
"title": "The History of Cats",
"description": "A brief history of cats.",
"keywords": {
"author": ["cat"],
"system": ["felis", "animalia"]
}
}
}
Ideally, if a user searches with the keyword cat or felis they should get a hit on this record. Currently, I do not receive any hits. Is this something that can be achieved through this query builder or another? Do I need to tweak mappings?
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.filter(QueryBuilders.matchQuery("content.keywords.*", keyword));
SearchRequestBuilder searchRequestBuilder = this.client.prepareSearch("my-index")
.setTypes("article")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(queryBuilder)
.setFrom(0)
.setSize(10)
.addSort(SortBuilders.scoreSort());
SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
return searchResponse;
Thanks
Drew
After some digging, this can be achieved by changing the match query to a multi-match query
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.filter(QueryBuilders.multiMatchQuery(keyword, "content.keywords.*"));
SearchRequestBuilder searchRequestBuilder = this.client.prepareSearch("my-index")
.setTypes("article")
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(queryBuilder)
.setFrom(0)
.setSize(10)
.addSort(SortBuilders.scoreSort());
SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
return searchResponse;
I have a Odata Query :
/ecommerceadmin/ODataService.svc/search?$select=status&$filter=id eq 'test.com'and name eq 'abc'
How can I implement the code in elastic search to get the data accordingly.What method in SearchSourceBuilder should be used?
You can probably easily get away with one match and one term query like this:
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders.*;
BoolQueryBuilder query = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("name", "abc")) // 1.
.filter(QueryBuilders.termQuery("id", "test.com")); // 2.
SearchResponse response = client.prepareSearch("ecommerce_index")
.setTypes("ecommerce_type")
.setQuery(query)
.setFetchSource(new String[]{"status"}, null) // 3.
.setFrom(0)
.setSize(10)
.execute()
.actionGet();
In the above code:
takes care of the name eq 'abc' $filter
takes care of the id eq 'test.com' $filter
takes care of the $select=status part
I am having trouble making this URL query work in Java, it does not return any results. but from the browser it returns all the results, here is the URL that returns result:
_search?pretty&q=*357*+AND+account_id:574fe92c9179a809fd76f0b8+AND+invalid:false
And here is my code (does not return any results):
FilterBuilder[] filtersArray = new FilterBuilder[2];
filtersArray[0] = FilterBuilders.termFilter("account_id", "574fe92c9179a809fd76f0b8");
filtersArray[1] = FilterBuilders.termFilter("invalid", false);
QueryBuilder query = QueryBuilders.filteredQuery(QueryBuilders.simpleQueryStringQuery("*357*"), FilterBuilders.andFilter(filtersArray));
SearchResponse response = esClient.prepareSearch(SecurityManager.getNamespace())
.addSort("created_time", SortOrder.DESC)
.setTypes(dataType)
.setQuery(query)
.addFields("_id")
.setFrom(page * size)
.setSize(size)
.setExplain(false)
.execute()
.actionGet();
Can someone tell me what is the best way to translate the URL query into a java query?
First off, the URL query you should use is this one
?q=*357*+AND+account_id:574fe92c9179a809fd76f0b8+AND+invalid:false
otherwise you'll have no constraint on account_id and invalid
Then, the exact translation of this new URL query in Java is
QueryBuilder query = QueryBuilders.queryStringQuery("*357* AND account_id:574fe92c9179a809fd76f0b8 AND invalid:false");
SearchResponse response = esClient.prepareSearch(SecurityManager.getNamespace())
.addSort("created_time", SortOrder.DESC)
.setTypes(dataType)
.setQuery(query)
.addFields("_id")
.setFrom(page * size)
.setSize(size)
.setExplain(false)
.execute()
.actionGet();
Notes:
queryStringQuery and not simpleQueryStringQuery
no filters as they are all in the query string already
I started to use ElasticSearch in my test project and cant figure out hot to create search for all fields. For instance we have some words as a search query and i want to find all indexed object in ElasticSearch, using Java API.
My obj have: id, name, adress, etc
I searched for this kind of info and wrote this:
Node node = nodeBuilder().node();
Client client = node.client();
RegexpFilterBuilder qFilter = FilterBuilders.regexpFilter("_all", (".*" + query + ".*").replace(" ", ".*"));
SearchResponse response = client.prepareSearch(index)
.setTypes(type)
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setPostFilter(qFilter)
.setFrom(0).setSize(100).setExplain(true)
.execute()
.actionGet();
SearchHit[] results = response.getHits().getHits();
System.out.println("Current results: " + results.length);
I also tried to use one field:
SearchResponse response = client.prepareSearch(index)
.setTypes(type)
.setSearchType(SearchType.QUERY_AND_FETCH)
.setQuery(termQuery(field, value))
.setFrom(0).setSize(100).setExplain(true)
.execute()
.actionGet();
I always get 0 result.
Can you show me, how to do this in right way in java?
Ok, i spent more time on documentation and i found a solution, hope it helps to someone else!
You just need to use QueryBuilders.multiMatchQuery, the value is our searching word and other strings are the columns where to search to.
SearchResponse response = client.prepareSearch(index)
.setTypes(type)
.setSearchType(SearchType.QUERY_AND_FETCH)
.setQuery(QueryBuilders.multiMatchQuery(value,
"name", "address1", "city", "postalCode",
"countryCode", "airportCode", "locationDescription",
"shortDescription"
))
.setFrom(0).setSize(100).setExplain(true)
.execute()
.actionGet();