How to search wrapper query with OpenSearchClient in Java SDK? - java

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.

Related

Converting a Java Map to a SearchSourceBuilder Elasticsearch 7.2 Java High Level API

I am writing a REST application (javax.ws.rs) that takes search requests from clients and submits them to the Elasticsearch high-level API. I want the clients
(browser based javascript mostly) to be able to compose their searches using the Elasticsearch REST API instructions.
The REST end point is defined like this:
#Path("list")
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response list(Map<String, Object> req) {
...
The following code would implement a security layer function and then pass the query on to SearchRequest object pretty much unchanged. So I don't want to build queries using QueryBuilders here.
I have tried the instructions in this article but it doesn't work. I think the createParser method has changed since that example was written. If someone could review this and suggest a solution that would be much appreciated.
UPDATE: Using ES 7.2 I have come up with the following code. There have been many changes in the API not all of which I understand but here is what seems like it should work.
XContentBuilder xcb = XContentFactory.contentBuilder(Requests.CONTENT_TYPE);
xcb.map(req);
String json = Strings.toString(xcb);
XContentParser parser = JsonXContent.jsonXContent.createParser(
NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, json);
SearchSourceBuilder ssb = new SearchSourceBuilder();
ssb.parseXContent(parser);
SearchRequest sr = new SearchRequest(Log.INDEX);
sr.source(ssb);
SearchResponse resp = client.search(sr, RequestOptions.DEFAULT);
I get an IOException off of the call to parseXContent. Looking with the debugger the string json has unprintable characters in it. Any suggestions?
I found a code pattern that works and it seems a bit convoluted but logical. There is no documentation anywhere that would lead you to this. This was pieced together from some fragments posted in message boards here and there.
try {
// convert the Map into a JSON string to parse. Alternatively
// you could just take the string directly from the HTTP request
// but the Map form makes it easy to manipulate.
XContentBuilder xcb = XContentFactory.jsonBuilder();
xcb.map(req);
String json = Strings.toString(xcb);
// Create an XContentParser and borrow a NamedXContentRegistry from
// the SearchModule class. Without that the parser has no way of
// knowing the query syntax.
SearchModule sm = new SearchModule(Settings.EMPTY, false, Collections.emptyList());
XContentParser parser = XContentFactory.xContent(XContentType.JSON)
.createParser(new NamedXContentRegistry(sm.getNamedXContents()),
LoggingDeprecationHandler.INSTANCE,
json);
// Finally we can create our SearchSourceBuilder and feed it the
// parser to ingest the request. This can throw and IllegalArgumentException
// if something isn't right with the JSON that we started with.
SearchSourceBuilder ssb = new SearchSourceBuilder();
ssb.parseXContent(parser);
// Now create a search request and use it
SearchRequest sr = new SearchRequest(Log.INDEX);
sr.source(ssb);
SearchResponse resp = client.search(sr, RequestOptions.DEFAULT);
I have tested this with a number of different JSON queries from the client and they all seem to work the way the direct REST API would. Here is an example:
{
from: 0,
size: 1000,
query: {
match_all: { boost: 1 }
},
sort: [
{ timestamp: { 'order': 'asc' } }
]
}
Hopefully this post will save someone else from the painful search I went through. I would appreciate any comments from anyone who could suggest a better way of doing this.
XContentBuilder xcb = XContentFactory.jsonBuilder();
xcb.map(req);
String json = Strings.toString(xcb);
SearchSourceBuilder ssb = new SearchSourceBuilder();
ssb.query(QueryBuilders.wrapperQuery(json));

How to do AND + OR query in ElasticSerch & Java

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));

Elasticsearch Wildcard in Path for Match Query

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;

elastic search query in java

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

fieldQuery(String, String) is undefined

i am new to elk,
I have an simple code of elasticsearch in Java like this :
Settings settings = Settings.settingsBuilder()
.put("cluster.name", "elasticsearch")
.put("client.transport.sniff", true).build();
TransportClient client = TransportClient.builder().settings(settings).build();
client.addTransportAddress(new InetSocketTransportAddress(new InetSocketAddress("1.2.3.4", 9200)));
SearchResponse response = client.prepareSearch("logstash-log*").setSearchType(SearchType.QUERY_AND_FETCH)
.setQuery(fieldQuery("host", "2.3.4.5"))
.setFrom(0).setSize(60).setExplain(true)
.execute()
.actionGet();
SearchHit[] results = response.getHits().getHits();
for (SearchHit hit : results) {
System.out.println(hit.getId()); //prints out the id of the document
Map<String,Object> result = hit.getSource(); //the retrieved document
}
System.out.println("test");
So, can you give me suggestion, I've looking for the solution
Thanks...
You should use termQuery("host", "2.3.4.5") instead.
fieldQuery() was an old query available in ES 0.90, which has been deprecated and removed.

Categories

Resources