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.

Resources, included to search layer:

Implemented features (as at September, 12):

Data in index

Every indexed object consist of such fields:

Indexed objects, which added to index:

  1. person (sub-tables: person_name, person_address, person_attribute);
  2. patient (sub-table : patient_identifier);
  3. provider (sub-table: provider_attribute);
  4. encounter (sub-table: form);
  5. concept (sub-tables: concept_name, concept_set, concept_desc);
  6. location (sub-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: 

In our case we use simple strategy, which provides updating indexes.

For each table/sub-table we create a river, which will update data for this table.

Search request

For searching data yo must execute GET request to server

Currently such search types supported:

  1. Getting all entities - HOST/TYPE;
     for example, to get all patients you can make GET request to HOST/patient
  2. Get all entities, suggesting to query: HOST/TYPE/query OR HOST/TYPE?q=query;
    for example, to get patient with name 'andriy' you can execute GET request to HOST/patient/andriy OR HOST/patient?q=andriy
    query - it can be uuid, or field,  specified for every type of resource. 

Supported options:

Example requests:

Authorization

All requests require authorization, currently BASIC authorization provided, with login and password.

First request may take long time, because all privileges and access rights will be checked and saved to local storage. With next requests to server only quick user checking will be perfomed, and all privileges will be taken from local storage. In 10 minutes after last request user data and privileges will be removed from local storage, and next request will also take a long time.

All user data indexed to Elasticsearch index, which allows make quick requests to ES for checking user privileges.

Options, which will be checked:

Search response

By default, response presented in JSON format.

Response structure for different resources: