2

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?

Zerg
  • 739
  • 4
  • 11
  • 22

2 Answers2

11

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();
Val
  • 207,596
  • 13
  • 358
  • 360
  • using the code you provided I get no results at all, even tried narrowing it to only filter by departments but still the hits list is empty. if your code is correct then do you know what can possibly be the reason? – Zerg Jan 03 '17 at 09:56
  • Are your fields analyzed or not? a term query is a exact match query, so your terms need to be exactly like the terms that have been indexed in the fields you're trying to match – Val Jan 03 '17 at 10:00
  • I had to use .setSize() in response, and it was in wrong place of the chain. it works now. – Zerg Jan 03 '17 at 10:28
  • Can you confirm, if _score is working with this BoolQuery? – Sophon Men Apr 03 '20 at 10:13
  • @SophonMen No you need to use `must()` instead of `filter()` and `matchQuery()` instead of `termsQuery()` – Val Apr 03 '20 at 11:21
  • @SophonMen please create a new question with your requirements described – Val Apr 03 '20 at 11:39
  • Ok, I created one here https://stackoverflow.com/questions/61011387/spring-boot-resthighlevelclient-elastic-search-on-combine-queries – Sophon Men Apr 03 '20 at 11:59
  • when use RestHighLevelClient we dont have prepareSearch.instead of that we can use searchSourceBuilder.query(query) – DaniyalVaghar Jul 14 '21 at 05:48
-1

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());
Kaliappan
  • 642
  • 9
  • 24
  • The source builder method from SearchRequest cannot be chained, it will overwrite the given sourceBuilder each time, so only the last one will be taken into consideration. – bogdan.rusu May 23 '20 at 15:49