How to rewrite ElasticSearch DSL query with the Java API - elasticsearch

I have got a working query for ElasticSearch, but I have problems to execute the same query with the Java API of ElasticSearch.
How can I express the query below with the Java API of ElasticSearch?
---
size: 0
query:
match_all: []
facets:
age:
statistical:
field : timestamp

It should be something like:
client.prepareSearch("yourindex")
.setTypes("yourtype")
.setQuery(QueryBuilders.matchAllQuery())
.addFacet(FacetBuilders.statisticalFacet("age").field("timestamp"))
.setSize(0)
.execute()
.actionGet();

You can convert your query DSL to a JSON string, and then wrap it with QueryBuilders.wrapperQuery() or WrapperQueryBuilder(), finally do the query with Java API like this.
SearchResponse response = client.prepareSearch("yourIndex")
.setTypes("yourType")
.setQuery(dslQB)
.setFrom(currentItem)
.setSize(pageSize)
.execute()
.actionGet();
`

Related

How to write multi key push in spring data mongodb?

I've the following aggregation query in mongodb:
{"$group": {"_id": "$code", "statusCount": {"$push": {"status": "$status", "count":"$total" }}}}
How can I write the $push part in spring data mongodb?
I've found how to do this. Hope it'll help others also:
DBObject dbObject = new BasicDBObject();
dbObject.put("status", "$status");
dbObject.put("total", "$total");
Aggregation agg = newAggregation(
group("code").push(dbObject).as("statusCount")
);

elasticsearch sort by _doc for scroll not returning any results

I am trying to run a scroll query and get the results by sorting on "_doc" field. But the scroll is always returning empty resultest. Below the scroll i am trying. I am using elasticsearch version 2.3.4
SearchResponse scrollResp = client.prepareSearch(indexName).setTypes(indexType)
.setScroll(TimeValue.timeValueMillis(scrollTimeout))
.addSort("_doc" , SortOrder.ASC)
.setSearchType(SearchType.QUERY_THEN_FETCH)
.setQuery(query)
.setFrom(pageIndex)
.setSize(scrollSize)
//.setFetchSource(true)
.execute()
.actionGet();
return scrollResp;
But if i replace the same query with sort on "id" field it works fine. Am i doing anything wrong here?
SearchResponse scrollResp = client.prepareSearch(indexName).setTypes(indexType)
.setScroll(TimeValue.timeValueMillis(scrollTimeout))
.addSort(new FieldSortBuilder("id"))
.setSearchType(SearchType.QUERY_THEN_FETCH)
.setQuery(query)
.setFrom(pageIndex)
.setSize(scrollSize)
//.setFetchSource(true)
.execute()
.actionGet();
return scrollResp;

Post Filter Query in Elasticsearch 2.3.3 using Java

I have built a web app on top of elasticsearch (v2.3.3). To filter the query, I am using post filter of elasticsearch. But I came to know that, if I use post filter then the performance benefit of filtering will be lost since I am not using any aggregation or differential filtering. (Reference: https://www.elastic.co/guide/en/elasticsearch/guide/current/_post_filter.html)
This is how my elasticsearch client looks like:
Client client = TransportClient.builder().build().addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"),
9300));
SearchResponse response = client.prepareSearch("index_name")
.setTypes("index_type")
.setQuery(QueryBuilders.simpleQueryStringQuery(query)
.field("newContent").field("T"))
.setPostFilter(QueryBuilders.termQuery(Collection, true))
.setFetchSource(new String[] { "U", "UE", "UD", "T" }, null)
.setVersion(true).addHighlightedField("newContent").setFrom(0)
.setSize(10).execute().actionGet();
I have also read that filtered query is depreciated in elasticsearch 2.x versions. Is there any other way which will help me to apply a filter before the query is executed? I might be missing something obvious. I would appreciate your help.
You simply need to bring the filter present in post filter inside a bool/filter query. Try to do hits instead:
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.simpleQueryStringQuery(query)
.field("newContent").field("T"))
.filter(QueryBuilders.termQuery(Collection, true));
SearchResponse response = client.prepareSearch("index_name")
.setTypes("index_type")
.setQuery(boolQuery)
.setFetchSource(new String[] { "U", "UE", "UD", "T" }, null)
.setVersion(true).addHighlightedField("newContent").setFrom(0)
.setSize(10).execute().actionGet();

Aggregations in Java client through JSON query - without AggregationBuilder

I am able to implement aggregation functionality via JSON query in HTTP based JEST client but not in TCP based Java client.
Through JEST client (HTTP REST based) it is possible to implement aggregation through query String.
JEST sample code:
JestClientFactory factory = new JestClientFactory();
HttpClientConfig httpClientConfig = new HttpClientConfig
.Builder("http://localhost:9201")
.build();
factory.setHttpClientConfig(httpClientConfig);
JestClient client = factory.getObject();
String queryString ="{\"query\":{\"match_all\": {}},\"aggs\":{\"avg1\":{\"avg\":{\"field\":\"age\"} } }}";
Search.Builder searchBuilder = new Search.Builder(queryString)
.addIndex("st1index")
.addType("st1type");
SearchResult response = client.execute(searchBuilder.build());
System.out.println(response.getJsonString());
client.shutdownClient();
Printing response of JEST client shows aggregation results.
Using TCP client in elasticsearch, aggregation is possible through AggregationBuilder.
When I tried to implement JSON query in TCP, it did not return aggregation results.
Is there any reason why TCP do not support aggregation through query string but supports with adding aggregation options?
TCP Java client sample code:
Edited
Removed WrapperQueryBuilder surrounding the queryString.
Settings settings = ImmutableSettings.settingsBuilder()
.put("cluster.name", "javaEscluster")
.put("node.name", "arivu").build();
Client client = new TransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress("localhost", 9303));
String queryString ="{\"match_all\": {},\"aggs\":{\"avg1\":{\"avg\":{\"field\":\"age\"} } }}";
SearchResponse response = client.prepareSearch("st1index").setTypes("st1type").setQuery(queryString).execute().actionGet();
System.out.println("Getresponse-->" +"Index-->"+ response.toString());
//closing node
client.close();
System.out.println("completed");
This code retrieves only search results and empty aggregation result data.
Edited:
Any reference material which explains the reason would be great.
In the main documentation of the WrapperQueryBuilder class, it is stated:
A Query builder which allows building a query given JSON string or binary data provided as input. This is useful when you want to use the Java Builder API but still have JSON query strings at hand that you want to combine with other query builders.
The keyword in here is the word query, i.e. the part named query in the request you send to the ES _search endpoint, i.e.:
{
"sort": {
... <--- whatever sorting definition you have goes here
},
"_source": {
... <--- whatever source definition you have goes here
},
"query": {
... <--- this is the content you can use with WrapperQueryBuilder
},
"aggs": {
... <--- whatever aggs definition you have goes here
}
}
WrapperQueryBuilder will only ever consider whatever you can fit inside that query section, so as you can see that doesn't include aggregations, which are in another top-level section of the request.
So, in the JSON query string you give, only the match_all will be considered, because that's the only valid token that is allowed to appear in the query section, the aggs:{...} part is not.
"{\"match_all\": {},\"aggs\":{\"avg1\":{\"avg\":{\"field\":\"age\"} } }}"
^ ^
| |
this is valid this is NOT valid

Why elasticsearch request body query analyzer not working?

When I use the simplest get query ( /index/_search?q=北京 ) , the results seems normal. But when I use the request body query , like below:
{
'query': {
'query_string':{
'query': '北京'
}
}
}
It seems elasticsearch not use analyzer I specific by the mapping setting, even I add the analyzer setting in the query body.
Can anyone help me find out what's wrong? Thank you.

Resources