How to write query in elastic Search which can work for both AND and OR operation for search?

54 views Asked by At

I'm trying to implement an elastic search query which can perform search like this

Here I want if I'm passing externalStudentId and DOB and FirstName in request body of API, then it must return all studnets which has this externalStudentId irrespective of their DOB along with the students which has this (DOB AND(FirstName || LastName || Email)).

And if only DOB and ExternalStudentId has been passed then all students with given externalStudentID irrespective of their DOB and all students with given DOB also.

 (DOB&firstName) OR (DOB&LastName) OR (DOB&Email)

But this code of mine isn't working like this, if I'm passing externalStudentID or DOB&FirstName altogether then it is still searching all the students which has different FirstName.

public List<Student> searchStudent(SearchStudentRequest request) {
        validateSearchRequest(request);
        List<Student> result = new ArrayList<Student>();
        try {
            SearchResponse<Student> response = osClient.search(s -> s
                            .index(indexName).size(recordSize)
                            .query(q -> q
                                    .bool(b -> {request.encryptValue(this.enc);
                                                Map<String, TermsQuery> t = buildTermQuery(request);
                                                String isShould = !t.isEmpty() && t.size() >= 2 ? "should" : "must";
                                                switch (isShould) {
                                                    case "should":
                                                        b.must(ms -> ms.bool(bq -> {
                                                            for (Map.Entry<String, TermsQuery> entry : t.entrySet()) {
                                                                bq.should(sh -> sh.terms(entry.getValue()));
                                                            }
                                                            bq.minimumShouldMatch("1");
                                                            return bq;
                                                        }));

                                                        break;
                                                    case "must":
                                                    default:
                                                        for (Map.Entry<String, TermsQuery> entry : t.entrySet()) {
                                                            System.out.println(entry);
                                                            b.must(ms -> ms.terms(entry.getValue()));
                                                        }
                                                        break;
                                                }
                                        if(null != request.getDob() && !request.getDob().isBlank()
                                        && request.getExternalStudentId() != null && request.getStudentPatientId().length > 0)
                                        {
                                            b.should(ms -> ms.match(QueryBuilders.match().field("dob").query(tq -> tq.stringValue(request.getDob())).build()));
                                            isShould = "should";
                                            if(request.getStudentType().equalsIgnoreCase(Constants.STUDENT_TYPES.SCH.toString())) {
                                                b.should(ms -> ms.nested(buildExternalStudentTermQuery(request.getExternalStudentId()).build()));
                                            }
                                            else if(request.getStudentType().equalsIgnoreCase(Constants.STUDENT_TYPES.CLG.toString())) {
                                                b.should(ms -> ms.terms(buildChannelExternalStudentIdTermQuery(request.getExternalStudentId())));
                                            }

                                            for (MatchQuery m : buildMatchQuery(request)) {
                                                System.out.println(m);
                                                isShould = "should";
                                                b.should(ms -> ms.match(m));
                                            }
                                            if (isShould.equals("should")) {
                                                b.minimumShouldMatch("1");
                                            }

                                            if (request.getStudentType() != null) {
                                                b.must(buildStudentTypeMatchQuery(request.getStudentType())._toQuery());
                                            }

                                            return b;

                                        }
                                        else if (request.getExternalStudentId() != null && request.getExternalStudentId().length > 0
                                                && request.getStudentType().equalsIgnoreCase(Constants.STUDENT_TYPES.CLG.toString()))
                                        {
                                            isShould = "should";
                                            b.should(ms -> ms.terms(buildChannelExternalStudentIdTermQuery(request.getExternalStudentId())));
                                        }
                                        else if (request.getExternalStudentId() != null && request.getExternalStudentId().length > 0
                                                && request.getStudentType().equalsIgnoreCase(Constants.STUDENT_TYPES.SCH.toString()))
                                        {
                                            isShould = "should";
                                            b.should(ms -> ms.nested(buildExternalStudentIdTermQuery(request.getExternalStudentId()).build()));
                                        }

                                        if(null != request.getDob() && !request.getDob().isBlank()) {
                                            b.must(ms->ms.match(QueryBuilders.match().field("dob").query(tq -> tq.stringValue(request.getDob())).build()));
                                        }
                                        for (MatchQuery m : buildMatchQuery(request)) {
                                            System.out.println(m);
                                            isShould = "should";
                                            b.should(ms -> ms.match(m));
                                        }
                                                if (isShould.equals("should")) {
                                                    b.minimumShouldMatch("1");
                                                }

                                                if (request.getStudentType() != null) {
                                                    b.must(buildStudentTypeMatchQuery(request.getStudentType())._toQuery());
                                                }

                                                return b;
                                            }
                                    )
                            )
                    , Student.class);

            TotalHits total = response.hits().total();
            boolean isExactResult = total.relation() == TotalHitsRelation.Eq;
            if (isExactResult) {
                if (total.value() > recordSize) {
                    //if we reach this exception then we have to implement pagination
                    log.error("Exception: fun searchPatient: total hits ({}) is greater than record size {} ", total.value(), recordSize);
                }
                List<Hit<Patient>> hits = response.hits().hits();
                for (Hit<Patient> hit : hits) {
                    Patient p = hit.source();
                    p.decryptValues(this.enc);
                    result.add(p);
                }
            } else {
                log.info("student not found");
            }

Need help in refractoring this code

I have added my code

I want it should support EXTERNALSTUDENTID OR (DOB & (FirstName || LastName || Email)) It isn't creating required query for now, it is only supporting EXTERNALPATIENTID OR DOB for now

0

There are 0 answers