Elastic searchquery by multiple value - java

I am using java QueryBuilder to search values in elasticQuery.Below is my code snippet.
Sample 2 json store in elastic search
{
"dataLayer":"sourcefeed"
}
{
"dataLayer":"sandbox"
}
BoolQueryBuilder qb = QueryBuilders.boolQuery();
qb.must(QueryBuilders.matchQuery("dataLayer",inputValue);
The input value can be either sourcefeed or sandbox or both,Depending on my input Value it should return the output.For single value it is working fine,But if I give input as InputValue="sourceFeed,sandbox" it is not working.Tried termsQuery also but it is not fetching correctly.Kindly help me to solve the problem.
Thanks Prakash

SearchSourceBuilder query = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
List<QueryBuilder> queryBuilders1 = new ArrayList<QueryBuilder>();
TermsQueryBuilder termsQuery = QueryBuilders.termsQuery("dataLayer.keyword", listOfValues);
queryBuilders1.add(termsQuery);
boolQueryBuilder.must(queryBuilders1.get(0));
query.query(boolQueryBuilder);
add sourceFeed and sandbox etc in one list and pass it in QueryBuilders.termsQuery.
Try this.Hope this will work.

Related

Do not retrieve all columns with Elastic search query

I have an Elastic search query and I would like to retrieve a certain column, not all.
I make my request in java with BoolQUEryBuilder which gives:
BoolQueryBuilder query = boolQuery();
query.must(wildcardQuery('value', value + "*"));
return findAll(query);
The method findAll :
protected List<T> findAll(final BoolQueryBuilder query) {
Query searchQuery = (new NativeSearchQueryBuilder()).withQuery(query).build();
SearchHits<T> searchHits = this.elasticsearchRestTemplate.search(searchQuery, this.getClazz(), this.elasticsearchRestTemplate.getIndexCoordinatesFor(this.getClazz()));
return (List)SearchHitSupport.unwrapSearchHits(searchHits);
}
I would like to add a filter on the columns. To illustrate in SQL this gives:
Select column_one, column_two from table;
Refer source filtering to fetch only few fields from Elasticsearch query results.
As explained in the same document example below code shows which fields to include and which to exclude.
String[] includeFields = new String[] {"title", "innerObject.*"};
String[] excludeFields = new String[] {"user"};
sourceBuilder.fetchSource(includeFields, excludeFields);
With Spring Data Elasticsearch, you should try this instead:
...
//include only specific fields
final SourceFilter sourceFilter = new FetchSourceFilter(new String[]{"column_one", "column_two"}, null);
// assemble the query
Query searchQuery = new NativeSearchQueryBuilder().withQuery(query).build();
searchQuery.addSourceFilter(sourceFilter);
...

How to use elasticsearch rangequery to find values that are less than or equal to a number value in Java API

Hello I'm new to Elastic Search and I'm trying to build an elastic search query using Java API. I have the following.
int count = 7
QueryBuilder findRangeNumber = QueryBuilders.rangeQuery("numberField").lte(count);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(findRangeNumber);
This return numberField that are equal to 12,6,4, and, 5. I want it to return values where numberField is less than or equal to count (so the number 6,5, and 4 in the example).
If I change number count to 12 it only return numberField that are equal to 12. I'm confuse to how this works and if it possible to it return any value of numberField that is less than or equal to count.
I also have tried the following with no luck
int count = 7
QueryBuilder findRangeNumber = QueryBuilders.rangeQuery("numberField").lte(count).gte(0);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(findRangeNumber);
This is what the query look like when I print out boolQueryBuilder
"must" : [
{
"range" : {
"numberField" : {
"from" : null,
"to" : 7,
"include_lower" : true,
"include_upper" : true,
"boost" : 1.0
}
}
}
],
This is what the full code part look like, of what I'm trying to do.
BoolQueryBuilder boolQuery = new BoolQueryBuilder();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
int count = 7
if (foo != null) {
boolQuery.should(QueryBuilders.matchQuery("something", matchSomething));
boolQuery.should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("foobar status")));
}
if (foobar != null) {
BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
queryBuilder.should(QueryBuilders.rangeQuery("someDateField").from(dateField));
queryBuilder.should(QueryBuilders.rangeQuery("numberField").lte(count));
boolQuery.must(queryBuilder);
}
searchSourceBuilder.query(boolQuery);
Any help would be appreciated!
You need to use RangeQueryBuilder to find values that are less than or equal to a given number
Try out this below code
int count=7;
RestHighLevelClient client = new RestHighLevelClient(restClientBuilder);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("numberField").lte(count);
searchSourceBuilder.query(rangeQueryBuilder);
SearchRequest searchRequest = new SearchRequest("my-index");
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
Update 1:
When you are searching for documents having numberField less than equal to 7, you are getting documents having numberField value 12,6,4,5.
The search result coming is correct. This is possible only if you have not defined an explicit index mapping, due to which when you have indexed the documents having numberField, then it would have been indexed as of text type (by default) instead of numeric field type.
Now, lexically "12","6","4","5" all are smaller than "7", therefore you are getting all the documents in your search result. And when querying for "lte":12, you only get a document having numberField equal to 12. This is because there is no document (among these 4) that is lexically smaller than 12.
You can get the index mapping of your index by using Get Mapping API.
For the range query to work correctly you need to explicitly define the index mapping for your index, where numberField should be mapped to a numeric field datatype. You need to delete your index and create a new index with a new index mapping.
{
"mappings": {
"properties": {
"numberField": {
"type": "integer"
}
}
}
}

Jest elastic search Query builder query with multiple match strings

I am trying to query elastic search in Java using Jest. I am using a query builder to construct the query.
QueryBuilder matchQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("id", "3434"))
.must(QueryBuilders.matchQuery("name", "name"))
.must(QueryBuilders.matchQuery("action", "login"))
.must(rangeQuery);
//i have this map now
Map<String , String> parameters = new HashMap<>();
parameters.put("id", "3433");
parameters.put("name", "name");
parameters.put("action", "login");
It would be great if some one can tell me if this can be constructed dynamically , like the matchQueries. For instance i would have three match queries , but i would have more. I can put my match query attributes in a Map. But if i iterate that how would we can define this boolQuery ? Anyone has any idea on this ?
Looking for something like this
QueryBuilder matchQuery = QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery(map.key, map.value))
.must(rangeQuery);
but how would i contruct this dynamically ?
You can simply iterate over your map and add each condition to the query, like this:
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
for(String key : parameters.keySet()){
boolQuery.must(QueryBuilders.matchQuery(key, parameters.get(key)));
}
boolQuery.must(rangeQuery);

Elasticsearch 2+ JAVA API orFilter

I am trying to write some Java code to query an ES5 instance. In ES1, you could OR and AND filters, orFilter and andFilter. What is the equivalent in ES5? I have tried -
QueryBuilder fb1 = QueryBuilders.termQuery("term1", "value1");
QueryBuilder fb2 = QueryBuilders.termQuery("term1", "value2");
QueryBuilder fb3 = QueryBuilders.termQuery("term2", "value3");
QueryBuilder fb = QueryBuilders.boolQuery()
.must(fb1)
.should(fb2)
This gives results that match fb1, so this is not an OR
QueryBuilder fb = QueryBuilders.boolQuery()
.must(fb1)
.must(fb2)
This gives no results, so the AND worked.
I want to figure out ways of constructing AND, OR queries
In order to make an AND query, put all the conditions into "must".
QueryBuilder fb = QueryBuilders.boolQuery().must(fb1).must(fb2);
In order to make an OR query, put all the conditions into "should".
QueryBuilder fb = QueryBuilders.boolQuery().should(fb1).should(fb2);
From ElasticSearch documentation (https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-compound-queries.html):
QueryBuilder qb = boolQuery()
.must(termQuery("content", "test1"))
.must(termQuery("content", "test4"))
.mustNot(termQuery("content", "test2"))
.should(termQuery("content", "test3"))
.filter(termQuery("content", "test5"));
must seems like it might be the equivalent of the AND and should like it's the equivalent of the OR.
You can use BoolQueryBuiler for these filters :
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("customerId", customerId))
boolQueryBuilder.mustNot(QueryBuilders.termsQuery("reason", "failed"));
boolQueryBuilder.should(QueryBuilders.termsQuery("action", "deny")).minimumNumberShouldMatch(1);
QueryBuilder queryBuilder=boolQueryBuilder;
new SearchContext().prepareSearch(sc.getIndexNames()).setTypes(sc.getTypeName()).setSearchType(SearchType.DFS_QUERY_THEN_FETCH).setQuery(queryBuilder);

Elasticsearch multiple condition query using java api

There are multiple documents containing around 100 fields each. I'd like to perform a following search trough elasticsearch Java API 5.x:
There are 3 fields I'd like to use for this search i.e.
department
job
name
I'd like to search the return documents that match fields like "department: D1", "department: D2", "job: J1", "job: J2" "name: N1"
I've been trying to do it this way
String[] departments = ["d1","d2","d3"];
String[] jobs = ["j1","j2","j3"];
String[] names = ["n1"];
MultiSearchRequestBuilder requestbuilder;
requestBuilder.add(client.prepareSearch().setQuery(QueryBuilders.termsQuery("department", departments)));
requestBuilder.add(client.prepareSearch().setQuery(QueryBuilders.termsQuery("job", jobs)));
requestBuilder.add(client.prepareSearch().setQuery(QueryBuilders.termsQuery("name", names)));
MultiSearchResponse response = requestBuilder.get();
However the queries are executed as if each was an individual query, i.e. in this example when j3 exists in d4, the document with d4 will be matched aswell
How to perform the search the way I mentioned? I've been trying numerous different queries and nothing seems to work, is there something I am missing?
You don't want to use MultiSearchRequestBuilder, you simply need to combine your three constraints in a bool/filter query:
BoolQueryBuilder query = QueryBuilders.boolQuery()
.filter(QueryBuilders.termsQuery("department", departments))
.filter(QueryBuilders.termsQuery("job", jobs))
.filter(QueryBuilders.termsQuery("name", names));
SearchResponse resp = client.prepareSearch().setQuery(query).get();
For Elasticsearch 5.6.4 of using HighRestClient, add required number of sourcebuilder...
static RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));
public static void multisearch() throws IOException{
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.termQuery("name", "vijay1"));
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("posts-1","posts-2").source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest);
RestStatus status = searchResponse.status();
System.out.println(searchResponse.toString());

Categories