Skip to content

Commit

Permalink
Jian | BAH-460 | search patient by name and gender using lucen search
Browse files Browse the repository at this point in the history
  • Loading branch information
Jian committed Apr 27, 2018
1 parent 4a2597d commit fc8d8f5
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.bahmni.module.bahmnicore.contract.patient.response.PatientResponse;
import org.openmrs.Patient;
import org.openmrs.RelationshipType;
import org.openmrs.module.emrapi.patient.PatientProfile;

import java.util.List;

Expand All @@ -19,6 +20,12 @@ List<PatientResponse> getPatientsUsingLuceneSearch(String identifier, String nam
String programAttributeFieldName, String[] addressSearchResultFields,
String[] patientSearchResultFields, String loginLocationUuid, Boolean filterPatientsByLocation, Boolean filterOnAllIdentifiers);

List<PatientResponse> getSimilarPatientsUsingLuceneSearch(String identifer, String name, String gender, String customAttribute,
String addressFieldName, String addressFieldValue, Integer length,
Integer offset, String[] customAttributeFields, String programAttributeFieldValue,
String programAttributeFieldName, String[] addressSearchResultFields,
String[] patientSearchResultFields, String loginLocationUuid, Boolean filterPatientsByLocation, Boolean filterOnAllIdentifiers);

public Patient getPatient(String identifier);

public List<Patient> getPatients(String partialIdentifier, boolean shouldMatchExactPatientId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@
import org.openmrs.Patient;
import org.openmrs.PatientIdentifier;
import org.openmrs.PatientIdentifierType;
import org.openmrs.Person;
import org.openmrs.PersonName;
import org.openmrs.RelationshipType;
import org.openmrs.api.context.Context;
import org.openmrs.api.db.hibernate.HibernatePatientDAO;
import org.openmrs.api.db.hibernate.PersonLuceneQuery;
import org.openmrs.api.db.hibernate.search.LuceneQuery;
import org.openmrs.module.bahmniemrapi.visitlocation.BahmniVisitLocationServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
Expand Down Expand Up @@ -100,6 +105,66 @@ public List<PatientResponse> getPatientsUsingLuceneSearch(String identifier, Str
return patientResponses;
}

@Override
public List<PatientResponse> getSimilarPatientsUsingLuceneSearch(String identifier, String name, String gender, String customAttribute,
String addressFieldName, String addressFieldValue, Integer length,
Integer offset, String[] customAttributeFields, String programAttributeFieldValue,
String programAttributeFieldName, String[] addressSearchResultFields,
String[] patientSearchResultFields, String loginLocationUuid,
Boolean filterPatientsByLocation, Boolean filterOnAllIdentifiers) {

validateSearchParams(customAttributeFields, programAttributeFieldName, addressFieldName);
PatientResponseMapper patientResponseMapper = new PatientResponseMapper(Context.getVisitService(),new BahmniVisitLocationServiceImpl(Context.getLocationService()));

List<Patient> patients = getPatientsByNameAndGender(name, gender, length);
List<Integer> patientIds = patients.stream().map(patient -> patient.getPatientId()).collect(toList());
Map<Object, Object> programAttributes = Context.getService(BahmniProgramWorkflowService.class).getPatientProgramAttributeByAttributeName(patientIds, programAttributeFieldName);
Set<Integer> uniquePatientIds = new HashSet<>();
List<PatientResponse> patientResponses = patients.stream()
.map(patient -> {
if(!uniquePatientIds.contains(patient.getPatientId())) {
PatientResponse patientResponse = patientResponseMapper.map(patient, loginLocationUuid, patientSearchResultFields, addressSearchResultFields,
programAttributes.get(patient.getPatientId()));
uniquePatientIds.add(patient.getPatientId());
return patientResponse;
}else
return null;
}).filter(Objects::nonNull)
.collect(toList());
return patientResponses;
}


private List<Patient> getPatientsByNameAndGender(String name, String gender, Integer length) {
HibernatePatientDAO patientDAO = new HibernatePatientDAO();
patientDAO.setSessionFactory(sessionFactory);
List<Patient> patients = new ArrayList<Patient>();
String query = LuceneQuery.escapeQuery(name);
PersonLuceneQuery personLuceneQuery = new PersonLuceneQuery(sessionFactory);
LuceneQuery<PersonName> nameQuery = personLuceneQuery.getPatientNameQueryWithOrParser(query, false);
/* person.gender does not work somehow in LuceneQuery, so the dirty way is to filter result with person's gender */
// if(gender != null && !gender.isEmpty()){
// nameQuery.include("person.gender", gender);
// }
List<PersonName> persons = nameQuery.list().stream()
.filter(
personName ->
personName.getPreferred()
&& checkGender(personName.getPerson(), gender)
).collect(toList());
persons = persons.subList(0, Math.min(length, persons.size()));
persons.forEach(person -> patients.add(patientDAO.getPatient(person.getPerson().getPersonId())));
return patients;
}

private Boolean checkGender(Person person, String gender) {
if(gender != null && !gender.isEmpty()){
return gender.equals(person.getGender());
} else {
return true;
}
}

private List<PatientIdentifier> getPatientIdentifiers(String identifier, Boolean filterOnAllIdentifiers, Integer offset, Integer length) {
FullTextSession fullTextSession = Search.getFullTextSession(sessionFactory.getCurrentSession());
QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(PatientIdentifier.class).get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public interface BahmniPatientService {

List<PatientResponse> luceneSearch(PatientSearchParameters searchParameters);

List<PatientResponse> searchSimilarPatients(PatientSearchParameters searchParameters, PatientResponseMapper patientResponseMapper);
List<PatientResponse> searchSimilarPatients(PatientSearchParameters searchParameters);

public List<Patient> get(String partialIdentifier, boolean shouldMatchExactPatientId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,22 @@ public List<PatientResponse> luceneSearch(PatientSearchParameters searchParamete
}

@Override
public List<PatientResponse> searchSimilarPatients(PatientSearchParameters searchParameters, PatientResponseMapper patientResponseMapper) {
List<PatientResponse> patients = new ArrayList<PatientResponse>();
Set<Person> persons = personService.getSimilarPeople(searchParameters.getName(), null, searchParameters.getGender());
for (Person person : persons) {
Patient patient = new Patient(person);
PatientResponse patientResponse = patientResponseMapper.map(
patient,
searchParameters.getLoginLocationUuid(),
searchParameters.getPatientSearchResultFields(),
searchParameters.getAddressSearchResultFields(),
patient.getPatientId());
patients.add(patientResponse);
}
return patients;
public List<PatientResponse> searchSimilarPatients(PatientSearchParameters searchParameters) {
return patientDao.getSimilarPatientsUsingLuceneSearch(searchParameters.getIdentifier(),
searchParameters.getName(),
searchParameters.getGender(),
searchParameters.getCustomAttribute(),
searchParameters.getAddressFieldName(),
searchParameters.getAddressFieldValue(),
searchParameters.getLength(),
searchParameters.getStart(),
searchParameters.getPatientAttributes(),
searchParameters.getProgramAttributeFieldValue(),
searchParameters.getProgramAttributeFieldName(),
searchParameters.getAddressSearchResultFields(),
searchParameters.getPatientSearchResultFields(),
searchParameters.getLoginLocationUuid(),
searchParameters.getFilterPatientsByLocation(), searchParameters.getFilterOnAllIdentifiers());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,35 @@ public void shouldNotReturnDuplicatePatientsEvenIfTwoIdentifiersMatches() {
assertTrue(patient.getExtraIdentifiers().contains("200006"));
}

@Test
public void shouldSearchSimilarPatientByPatientName() {
String[] addressResultFields = {"city_village"};
List<PatientResponse> patients = patientDao.getSimilarPatientsUsingLuceneSearch("", "Peet", "", null, "city_village", "", 100, 0, null,"",null,addressResultFields,null, "c36006e5-9fbb-4f20-866b-0ece245615a1", false, false);
PatientResponse patient1 = patients.get(0);
PatientResponse patient2 = patients.get(1);

assertEquals(2, patients.size());
assertEquals(patient1.getGivenName(), "Horatio");
assertEquals(patient1.getMiddleName(), "Peeter");
assertEquals(patient1.getFamilyName(), "Sinha");
assertEquals(patient2.getGivenName(), "John");
assertEquals(patient2.getMiddleName(), "Peeter");
assertEquals(patient2.getFamilyName(), "Sinha");
}

@Test
public void shouldSearchSimilarPatientByPatientNameAndGender() {
String[] addressResultFields = {"city_village"};
List<PatientResponse> patients = patientDao.getSimilarPatientsUsingLuceneSearch("", "Peet", "F", null, "city_village", "", 100, 0, null,"",null,addressResultFields,null, "c36006e5-9fbb-4f20-866b-0ece245615a1", false, false);
PatientResponse patient1 = patients.get(0);

for(PatientResponse response: patients) {
System.out.println(response.getGivenName() + " " + response.getMiddleName() + " " + response.getFamilyName());
}
assertEquals(1, patients.size());
assertEquals(patient1.getGivenName(), "John");
assertEquals(patient1.getMiddleName(), "Peeter");
assertEquals(patient1.getFamilyName(), "Sinha");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@
import org.bahmni.module.bahmnicore.contract.patient.PatientSearchParameters;
import org.bahmni.module.bahmnicore.contract.patient.mapper.PatientResponseMapper;
import org.bahmni.module.bahmnicore.contract.patient.response.PatientConfigResponse;
import org.bahmni.module.bahmnicore.contract.patient.response.PatientResponse;
import org.bahmni.module.bahmnicore.dao.PatientDao;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.openmrs.Concept;
import org.openmrs.Person;
import org.openmrs.PersonAttributeType;
import org.openmrs.api.ConceptService;
import org.openmrs.api.PersonService;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static junit.framework.Assert.assertEquals;
import static org.mockito.Mockito.anyInt;
Expand All @@ -32,10 +28,6 @@ public class BahmniPatientServiceImplTest {
private ConceptService conceptService;
@Mock
private PatientDao patientDao;
@Mock
private PatientSearchParameters searchParameters;
@Mock
private PatientResponseMapper patientResponseMapper;

private BahmniPatientServiceImpl bahmniPatientService;

Expand Down Expand Up @@ -78,16 +70,4 @@ public void shouldGetPatientByPartialIdentifier() throws Exception {
verify(patientDao).getPatients("partial_identifier", shouldMatchExactPatientId);
}

@Test
public void shouldGetSimiliarPatientResponseFromPersonSet() throws Exception {
Set<Person> persons = new HashSet<Person>();
persons.add(new Person());
persons.add(new Person());
when(personService.getSimilarPeople(searchParameters.getName(), null, searchParameters.getGender())).thenReturn(persons);

List<PatientResponse> response = bahmniPatientService.searchSimilarPatients(searchParameters, patientResponseMapper);

assertEquals(response.size(), 2);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ public ResponseEntity<AlreadyPaged<PatientResponse>> searchSimilarPerson(HttpSer
RequestContext requestContext = RestUtil.getRequestContext(request, response);
PatientSearchParameters searchParameters = new PatientSearchParameters(requestContext);
try {
PatientResponseMapper patientResponseMapper = new PatientResponseMapper(Context.getVisitService(),new BahmniVisitLocationServiceImpl(Context.getLocationService()));
List<PatientResponse> patients = bahmniPatientService.searchSimilarPatients(searchParameters, patientResponseMapper);
List<PatientResponse> patients = bahmniPatientService.searchSimilarPatients(searchParameters);
AlreadyPaged alreadyPaged = new AlreadyPaged(requestContext, patients, false);
return new ResponseEntity(alreadyPaged, HttpStatus.OK);
}catch (IllegalArgumentException e){
Expand Down

0 comments on commit fc8d8f5

Please sign in to comment.