Home > Software design >  Elastic Search query Generation for normal query and regular expression
Elastic Search query Generation for normal query and regular expression

Time:03-11

I have students information placed in Elastic search db. I am trying to perform a search

  1. Fetch all the records where the student grade is "A"

     {
        "query":{
           "bool":{
              "must":[
                 {
                    "match":{
                       "grade":{
                          "query":"A",
                          "operator":"OR",
                          "prefix_length":0,
                          "max_expansions":50,
                          "fuzzy_transpositions":true,
                          "lenient":false,
                          "zero_terms_query":"NONE",
                          "auto_generate_synonyms_phrase_query":true,
                          "boost":1.0
                       }
                    }
                 }
              ],
              "adjust_pure_negative":true,
              "boost":1.0
           }
        }
     }
    
  2. Fetch all the records where the city value begins with B*

     {
        "query":{
           "bool":{
              "must":[
                 {
                    "regexp":{
                       "city":{
                          "value":"B*",
                          "flags_value":65535,
                          "max_determinized_states":10000,
                          "boost":1.0
                       }
                    }
                 }
              ],
              "adjust_pure_negative":true,
              "boost":1.0
           }
        }
     }
    
  3. For generating search query

     SearchSourceBuilder elasticSearchSourceBuilder = new SearchSourceBuilder();
     BoolQueryBuilder esQueryBuilder = QueryBuilders.boolQuery();
     Map<String,List<String>> searchCriteriaMap = new HashMap();
     searchCriteriaMap.put("grade", Arrays.asList(new String[] {"A"}));
     for(Map.Entry<String, List<String>> entry :searchCriteriaMap.entrySet()) {
         List<String> parameterValueList = searchCriteriaMap.get(entry.getKey());
         String parameterValue = String.join(",", parameterValueList);
         MatchQueryBuilder matchQueryBuilder= QueryBuilders.matchQuery(entry.getKey(), parameterValue);
    
         esQueryBuilder.must(matchQueryBuilder);
    
     }
    
  4. For Generating regular Expression query:

     SearchSourceBuilder elasticSearchSourceBuilder = new SearchSourceBuilder();
     BoolQueryBuilder esQueryBuilder = QueryBuilders.boolQuery();
     Map<String,List<String>> searchCriteriaMap = new HashMap();
     searchCriteriaMap.put("city", Arrays.asList(new String[] {"Bangalore*"}));
     //queryParameterMap1.put("school.name", Arrays.asList(new String[] {"Joseph"}));
     for(Map.Entry<String, List<String>> entry :searchCriteriaMap.entrySet()) {  
         RegexpQueryBuilder matchQueryBuilder= QueryBuilders.regexpQuery("city", "Bang*");
         esQueryBuilder.must(matchQueryBuilder);
    
     }
    

How do I handle both these conditions in a single query, that is the student whose grade is A and the city value should begin with B*. For generating the query, I have used Java Elastic search query Builder.

The student records are:

{
   "name":"Anthon",
   "id":"JO-01",
   "courses":[
      "English",
      "Science",
      "Mathematics",
      "Physics",
      "Biology"
   ],
   "grade":"A",
   "cgpa":8.3,
   "schoolName":"Joseph Higher Seconday School",
   "city":"Bangalore",
   "dateOfJoining":"Jul 24, 3914 12:00:00 AM"
}

CodePudding user response:

You can just combined the must clause of both queries

Query:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "grade": {
              "query": "A"
            }
          }
        },
        {
          "regexp": {
            "city.keyword": {
              "value": "B.*"
            }
          }
        }
      ]
    }
  }
}

Java Code:

SearchSourceBuilder elasticSearchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder esQueryBuilder = QueryBuilders.boolQuery();
MatchQueryBuilder matchQueryBuilder= QueryBuilders.matchQuery("grade", "A");
RegexpQueryBuilder regxQueryBuilder= QueryBuilders.regexpQuery("city", "B*");
esQueryBuilder.must(matchQueryBuilder);
esQueryBuilder.must(regxQueryBuilder);
System.out.println(esQueryBuilder.toString());

Here, if you are using multi-field then you need to give city.keywordand you need to pass query same as value of field like B.* and if you define city field as text then you need to use city as field name and value as b.*

  • Related