Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Short Description:

The basic idea of this project - building a fast, responsive search layer for medical data. Currently, the search layer in OpenMRS performs many unecessary checks before accessing the data. Our task is to bring that data into a lightweight node.js search layer. Before each database lookup, we must perform a quick check using the OpenMRS API to see if the user is allowed to view that particular resource.

...

  • Person

  • Patient
  • Provider
  • Location
  • Encounter
  • Obs
  • Order
  • Concept 
  • Drug
  • Patientlist

Implemented features (as at September, 12):

  • adding/removing rivers for all types of resource (which provide automatic data indexing from MySQL database)
  • searching for all types of resources using GET requests
  • authorization, with checking user privileges
  • smart searching 
  • unit tests

**To be implemented:

  • patientlist

Data in index

Every indexed object consist of such fields:

...

Indexed objects, which added to index:

  1. person (subtablessub-tables: person_name, person_address, person_attribute);
  2. patient (subtable sub-table : patient_identifier);
  3. provider (subtablesub-table: provider_attribute);
  4. encounter (subtablesub-table: form);
  5. concept (subtablessub-tables: concept_name, concept_set, concept_desc);
  6. location (subtablessub-tables: location_tag, location_attribute);
  7. drug;
  8. obs;
  9. order.
  10. patientlist

River setup

elastic-search uses river inteface for adding/updating indexes. A river is a pluggable service running within elasticsearch cluster pulling data (or being pushed with data) that is then indexed into the cluster.

For fetching data from MySQL database we use MySQL river. River can be setuped using request to Elasticsearch with next params (for example)

curl -XPUT 'localhost:9200/_river/my_jdbc_river/_meta' -d '{
            "type" : "jdbc",
            "jdbc" : {
                "driver" : "com.mysql.jdbc.Driver",
                "url" : "jdbc:mysql://" + dbHost + ":3306/" + dbName,
                "user" : dbUser,
                "password" :dbPass,
                "sql" : sql,
                "poll" : "10m"
                "strategy" : "simple"
            },
            "index" : {
                "index" : indexName,
                "type" : indexType
            }
}'

sql - sql statements for fetching data froom MySQL database;

index - index name;

poll - time interval for updating;

type - index type;

strategy - the strategy of updating indexes, there are 3 strategies: 

...

Supported options:

  • ?q= - get items by tag;
  • ?quick= -don't include data of sub-tables to response;
  • ?class= (concept only) - get concepts by selected concept class;
  • ?patient= (obs only) - get obs by selected patient uuid;
  • ?location= (patientlist only) - get patients by selected location;
  • ?endDate= (patientlist only) - get patients for selected time period of encounter;
  • ?startDate= (patientlist only) - get patients for selected time period of encounter;
  • ?obs= (patientlist only) - if set it to "false" you will not get list of obs for each encounter;
  • ?encounterType= (patientlist only) - get patients by selected encounter type.

Example requests:

  • Person : HOST/person?q=[name,uuid] ; OR HOST/person/[name, uuid]; 
  • Patient : HOST/patient?q=[name,uuid] ; OR HOST/patient/[name, uuid];
  • Provider : HOST/provider?q=[name,uuid] ; OR HOST/provider/[name, uuid];
  • Location : HOST/location?q=[name,uuid] ; OR HOST/location/[name, uuid];
  • Encounter : HOST/encounter?q=[patient_name,uuid] ; OR HOST/encounter/[patient_name, uuid];
  • Obs : HOST/obs?q=[patient_name,uuid] ; OR HOST/obs/[patient_name, uuid];
  • Order : HOST/order?q=[patient_name,uuid] ; OR HOST/order/[patient_name, uuid];
  • Concept :HOST/concept?q=[name,uuid]&class=[concept_class] ; OR HOST/concept/[name, uuid]?class=[concept_class];
  • Drug :HOST/drug?q=[name,uuid] ; OR HOST/drug/[name, uuid].

...