Filtering in high level rest java elasticsearch client over multiple fields - elasticsearch

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

Related

How to get the data from multiple index in elastic search

I have a three index, all three index have a diff structure of document(nested), I tried to join the index's,But in ES there is no joins.So, how can i get the data from multiple index's through java high level api??
Any help will be appreciate, thanks in adavnce
SearchRequest searchRequest = new SearchRequest("index_1","index_2","index_3");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy"));
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
You can query multiple Elasticsearch indices in one search operation. The indices can be specified with wildcard patterns, or by listing multiple indices using commas as separators.
But with Client API(Java high level api), You've to convert the index names inside SearchRequest into an array of Strings. Java varargs expects an Array. Not sure but something like below.
String[] indexArray = new String[]{"index_1","index_2","imdex_3"}
SearchRequest searchRequest = new SearchRequest(indexArray);
If it doesn't help the try with Multisearch API, See: https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-high-multi-search.html#java-rest-high-multi-search

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.

NotQueryBuilder elasticsearch 2.4 execution modes

what is the alternative for .execution("and") in elastic search 2.4? and what exactly its usage –
NotFilterBuilder excVariantsFilter = FilterBuilders.notFilter(FilterBuilders.termsFilter("products", productIds.toArray()).execution("and"));
Filters and queries have been merged in ES 2.0 and the execution mode was only useful in a filter context, so there's no need anymore for that execution parameter in terms queries.
So if you want an equivalent behavior to this
NotFilterBuilder excVariantsFilter = FilterBuilders.notFilter(FilterBuilders.termsFilter("products", productIds.toArray()).execution("and"));
you can now write it like this:
BoolQueryBuilder excVariantsFilter = QueryBuilders.boolQuery();
for (String productId : productIds.toArray()) {
excVariantsFilter.mustNot(QueryBuilders.termQuery("products", productId));
}
It will produce a bool/must_not query containing a term query for each productId, which is equivalent to the previous not filter containing a terms query with and execution mode

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