How to make query for elasticsearch in spring boot like we do in sense plugin - elasticsearch

this is query which i have done in sense
GET /_search?q=2016
it searches in whole db and get results for all entries which has "2016" in any field.

Giving q as query paramater run as query string query. So you have to use java api for Query String. You can use :
SearchResponse response = client.prepareSearch("index_name")
.setTypes("type1Name")
.setQuery(QueryBuilders.queryString("2016"))
.execute()
.actionGet();

Related

APOC Elasticsearch query format

I am using Neo4j 4.0.3, Elasticsearch 6.8.3 and APOC.
I want to run an Elasticsearch aggregation query through Neo4J using the APOC Elasticsearch procedure.
The query is defined in the request body and works on Elasticsearch but I'm not sure how to construct the query parameter through the procedure. In Elasticsearch I can pass the request body as a source parameter (with a source content type of JSON).
To demonstrate, I've tried to get a simple query working.
This works in Elasticsearch:
GET http://localhost:9200/trends/trend/_search?source={"query": {"match" : {"type" : "ENTITY"}}}&source_content_type=application/json
but when I try this through the ES procedure:
CALL apoc.es.query('elasticsearch:9200', 'trends', 'trend', 'source={"query":{"match":{"type":"ENTITY"}}}&source_content_type=application/json', null)
Neo4J gives the following error:
Failed to invoke procedure `apoc.es.query`: Caused by: java.net.URISyntaxException: Illegal character in query at index 54: http://elasticsearch:9200/trends/trend/_search?source={"query":{"match":{"type":%22ENTITY%22%7D%7D%7D````
What do I need to do to pass the query correctly?
Got it to work, I overlooked the payload parameter. So the APOC call was this:
CALL apoc.es.query('elasticsearch:9200', 'trends', 'trend', null, '{"query":{"match":{"type":"ENTITY"}}}')
Alternatively I could have passed the query as a Map
CALL apoc.es.query('elasticsearch:9200', 'trends', 'trend', apoc.map.fromPairs([
["source_content_type", "application/json"],
["source", '{"query":{"match":{"type":"ENTITY"}}}']
]), null)
If you want to use a scroll ID and also a payload to specify the query, something like this works:
CALL apoc.es.query('localhost','indexName','doc','scroll=1m','{
"query":{
"query_string":{
"query": "name:somebody AND date:[now-30d TO now]"
}
},
"size":"1000"
}') yield value
with value._scroll_id as scrollId, value.hits.hits as hits
// Do something with hits
UNWIND hits as hit
return hit
This format makes editing the query easier: I've found inconsistent results and URL escaping rules when putting the query in a string in the fourth parameter position.
See https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html and https://neo4j.com/docs/labs/apoc/4.0/database-integration/elasticsearch/

Filtering in high level rest java elasticsearch client over multiple fields

I need to filter over a few fields.
All is ok if I filter over one but adding the second one gives wrong results.
Fields are REQ_ID and CATEGORY
In Kibana, following will return expected results
REQ_ID: '1574778361496' and CATEGORY: 'WARNING'
In java, I tried with:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
final SimpleQueryStringBuilder sqb = QueryBuilders.simpleQueryStringQuery("REQ_ID: '1574778361496' and CATEGORY: 'WARNING'");
searchSourceBuilder.query(sqb);
searchRequest.source(searchSourceBuilder);
This yields results equivalent to upper having or instead of and, logically.
I also tried:
final BoolQueryBuilder bool = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("REQ_ID", "1574778361496"))
.filter(QueryBuilders.termQuery("CATEGORY", "WARNING"))
;
searchSourceBuilder.query(bool);
This yields no results.
Not sure if this is a bug due to strange nature of high rest java client or am I reading the wrong manual?
client version: 7.4.2
elk version(sebp/elk:740): 7.4.0
Kibana use the Kibana Query Language which is a little different of the Lucene language.
You can switch to Lucene on the top right of Kibana.
But you need no use the correct Lucene syntax (both in kibana with lucene syntax and in your java code), with upper operators :
REQ_ID: 'id1' AND CATEGORY: 'WARNING'
^^^
And you must use a QueryStringQueryBuilder instead of a SimpleQueryStringBuilder :
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
final QueryStringQueryBuilder sqb = QueryBuilders.queryStringQuery("REQ_ID: 'id1' and CATEGORY: 'WARNING'");
searchSourceBuilder.query(sqb);
searchRequest.source(searchSourceBuilder);
You do not need the SimpleQueryString query for your use-case. Using a TermQuery is fine. I recommend to use the un-analyzed field in this case since you are only matching on an exact value. You could wrap this in a Bool clause within filter clauses. Example:
QueryBuilder query = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("REQ_ID.keyword", "1574778361496"))
.filter(QueryBuilders.termQuery("CATEGORY.keyword", "WARNING"));

How to create FiltersAggregation query using JEST builders?

How can I create FiltersAggregation query using JEST AggregationBuilders or similar? I looked at FiltersAggregationIntegrationTest but query part is defined directly by JSON and I need something more like AggregationBuilders (as I'm using this for standard term aggregation for example)
Link to FiltersAggregationIntegrationTest:
https://github.com/searchbox-io/Jest/blob/master/jest/src/test/java/io/searchbox/core/search/aggregation/FiltersAggregationIntegrationTest.java
I've one possibility:
FilterAggregationBuilder testFilter = AggregationBuilders.filter("test");
testFilter.filter(FilterBuilders.typeFilter("typeName"));
new SearchSourceBuilder().aggregation(testFilter);
This is a filter by Type, but the FilterBuilders has a termFilter too.
Here is a solution that may work, I've cross posted this to the Jest github issue as well.
QueryBuilder filterTermsQuery = QueryBuilders.termsQuery("fieldName", "value1", "value2", "value3");
SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource()
.query(boolQueryBuilder)
.size(0)
.aggregation(
AggregationBuilders
.filter("filterAggName") // returns FilterAggregationBuilder
.filter(filterTermsQuery));
The gist is that you want to create a search source builder to use in the jest client, and supply that with and aggregation (which could also include sub-aggregations by chaining sub-aggregations on the AggregationBuilders method). Then define an aggregation of filter type available in AggregationBuilders. This returns a new builder of FilterAggregationBuilder where you can provide any QueryBuilder as the filter aggregation type. According to documentation, the .filter(termsQuery) call will cause only the documents that match the filter to fall into the bucket of this filter.
Hopefully this will resolve your issue unless I misunderstood your use case.

Fuzzify existing ElasticSearch Java API query

I have an existing ElasticSearch query that uses the Java API:
BoolQueryBuilder queryBuilder =
boolQuery().should(queryStringQuery(theUsersQueryString));
SearchResponse response = client.prepareSearch(...).setQuery(queryBuilder);
Now I want to add fuzziness to this, to allow minor misspellings to still return something to the user. My guess was that adding fuzziness parameters to the QueryBuilders object would be fruitful:
boolQuery().should(queryStringQuery(theUsersQueryString)
.fuzziness(Fuzziness.ONE)
.fuzzyMaxExpansions(4)
.fuzzyPrefixLength(2));
Unfortunately this doesn't seem to work and I have so far been unable to find good documentation for this. For example, I have the string John Deere in my database. If I use the query string deere I get a match, but not if I use query strings Deeree or Deeer.
My question is: how should I correctly fuzzify my query?
I opted to create a new query rather than modifying my existing one.
MultiMatchQueryBuilder fuzzyMmQueryBuilder = multiMatchQuery(
theUsersQueryString, "field1", "field2", ... , "fieldn").fuzziness("AUTO");
BoolQueryBuilder b = boolQuery().should(fuzzyMmQueryBuilder);
SearchRequestBuilder srb = client.prepareSearch(...).setQuery(b)...
SearchResponse res = srb.execute().actionGet();
This query exhibits fuzzy behaviour.

Elastic Search: include multiple field in query

I am new to Elastic Search.I want to include multiple field in my search query something like:
Title=my title and city=mycity or country = mycountry
How can I execute this kind of query using java client? I tried this
SearchResponse response = client.prepareSearch("titan")
.setTypes("vertex")
.setSearchType(SearchType.QUERY_AND_FETCH)
.setQuery(QueryBuilders.fieldQuery("title", "mytitle"))
.setQuery(QueryBuilders.fieldQuery("city", "mycity"))
.setFrom(0).setSize(60).setExplain(true)
.execute()
.actionGet();
but didn't work
You have to do booleanQuery there, I believe.
Something like:
SearchResponse response = client.prepareSearch("titan")
.setTypes("vertex")
.setSearchType(SearchType.QUERY_AND_FETCH)
.setQuery(QueryBuilders.boolQuery()
.must(QueryBuilders.fieldQuery("title", "mytitle"))
.should(QueryBuilders.fieldQuery("city", "mycity"))
.should(QueryBuilders.fieldQuery("country", "mycountry")))
.setFrom(0).setSize(60).setExplain(true)
.execute()
.actionGet();
The rules for boolean queries, in a nutshell, are that all must clauses are expected to be true, and at least one from the should clauses are expected to be true (the amount of should clauses which has to be true can be changed, one is the default).

Resources