Search Data
Once an entity (such as a patient or a medical record) is created, you can always retrieve it using its ID. However, in most cases, you might not have the ID of the entity you need. Therefore, the Cardinal SDK allows you to search data by their content using filters.
The following examples provide insights into how to search data using the filter mechanism. For a more comprehensive understanding, check this how to.
In the first code snippet, all patients whose name matches the query string provided by the user and who are shared with the current user will be returned:
- Kotlin
- Python
- Typescript
- Dart
print("Enter a name: ")
val nameToSearch = readln()
val patientIterator = sdk.patient.filterPatientsBy(
PatientFilters.byNameForSelf(nameToSearch)
)
name_to_search = input("Enter a name: ")
patient_iterator = sdk.patient.filter_patients_by_blocking(
PatientFilters.by_name_for_self(name_to_search)
)
const nameToSearch = await readLn("Enter a name: ")
const patientIterator = await sdk.patient.filterPatientsBy(
PatientFilters.byNameForSelf(nameToSearch)
)
String nameToSearch = // This is provided by the user through the UI
final patientIterator = await sdk.patient.filterPatientsBy(
await PatientFilters.byNameForSelf(nameToSearch)
);
PatientFilters.byNameForSelf
defines the options used to retrieve the patients, while the filterPatientsBy
method
is responsible for actually getting them. This method returns an iterator with two methods: hasNext()
, which returns
true
if there is at least one more entity available, and next(X)
, which retrieves up to the next X available
entities, with a minimum of 1.
Here’s an example of how to use this iterator:
- Kotlin
- Python
- Typescript
- Dart
var patient: Patient? = null
while (patientIterator.hasNext() && patient == null) {
val p = patientIterator.next(1).first()
prettyPrint(p)
print("Use this patient? [y/N]: ")
val use = readln().trim().lowercase() == "y"
if (use) {
patient = p
}
}
if (patient == null) {
println("No matching patient found")
return
}
patient = None
while patient_iterator.has_next_blocking() and patient is None:
p = patient_iterator.next_blocking(1)[0]
pretty_print_patient(p)
use = input("Use this patient? [y/N]: ").strip().lower() == "y"
if use:
patient = p
if patient is None:
print("No matching patient found")
return
let patient: Patient | null = null
while ((await patientIterator.hasNext()) && patient == null) {
const p = (await patientIterator.next(1))[0]
prettyPrintPatient(p)
const use = (await readLn("Use this patient? [y/N]: ")).trim().toLowerCase() === "y"
if (use) {
patient = p
}
}
if (patient == null) {
console.log("No matching patient found")
return
}
Patient? patient;
while ((await patientIterator.hasNext()) && patient == null) {
final p = (await patientIterator.next(1)).first;
showPatientOnTheUi(p);
final use = readChoiceOfTheUser();
if (use) {
patient = p;
}
}
The same logic can be applied to medical data, where you can leverage the secret link between a patient and another entity:
- Kotlin
- Python
- Typescript
- Dart
val contactIterator = sdk.contact.filterContactsBy(
ContactFilters.byPatientsForSelf(listOf(patient))
)
if (!contactIterator.hasNext()) {
println("No matching contacts found")
}
while(contactIterator.hasNext()) {
val contact = contactIterator.next(1).first()
prettyPrint(contact)
print("Press enter for next contact")
readln()
}
contact_iterator = sdk.contact.filter_contacts_by_blocking(
ContactFilters.by_patients_for_self([patient])
)
if not contact_iterator.has_next_blocking():
print("No matching contacts found")
while contact_iterator.has_next_blocking():
contact = contact_iterator.next_blocking(1)[0]
pretty_print_contact(contact)
input("Press enter for next contact")
const contactIterator = await sdk.contact.filterContactsBy(
ContactFilters.byPatientsForSelf([patient])
)
if (!(await contactIterator.hasNext())) {
console.log("No matching contacts found")
}
while(await contactIterator.hasNext()) {
const contact = (await contactIterator.next(1))[0]
prettyPrintContact(contact)
await readLn("Press enter for next contact")
}
final contactIterator = await sdk.contact.filterContactsBy(
await ContactFilters.byPatientsForSelf([patient])
);
if (!(await contactIterator.hasNext())) {
showErrorMessageForNoContactsFound();
}
while(await contactIterator.hasNext()) {
final contact = (await contactIterator.next(1)).first;
showContactOnTheUI(contact);
await waitForUserConfirmationToShowNext();
}
In this case, the filter method returns all the Contacts
shared with the current user that have an encrypted link to
one of the Patients
passed as a parameter.
Since the link between Patient
and Contact
is encrypted, the user must also have access to the Patient
to use this filter.
As with the previous example, the method returns an iterator that can be used to retrieve all the matching Contacts
.
The additional information stored in an entity to provide additional context (like the identifiers in a Service) can also be used for filtering:
- Kotlin
- Python
- Typescript
- Dart
var choice = -1
while (choice < 0 || choice >= 3) {
println("0. blood pressure")
println("1. heart rate")
println("2. x ray")
print("Enter your choice: ")
choice = readln().trim().toIntOrNull() ?: 0
}
val identifier = when(choice) {
0 -> Identifier(system = "cardinal", value = "bloodPressure")
1 -> Identifier(system = "cardinal", value = "ecg")
2 -> Identifier(system = "cardinal", value = "xRay")
else -> throw IllegalArgumentException("Invalid choice")
}
val serviceIterator = sdk.contact.filterServicesBy(
ServiceFilters.byIdentifiersForSelf(listOf(identifier))
)
if (!serviceIterator.hasNext()) {
println("No matching services found")
}
while (serviceIterator.hasNext()) {
val service = serviceIterator.next(1).first()
prettyPrint(service)
print("Press enter for next service")
readln()
}
choice = -1
while choice < 0 or choice >= 3:
print("0. blood pressure")
print("1. heart rate")
print("2. x ray")
try:
choice = int(input("Enter your choice: ").strip())
except ValueError:
choice = -1
if choice == 0:
identifier = Identifier(system="cardinal", value="bloodPressure")
elif choice == 1:
identifier = Identifier(system="cardinal", value="ecg")
else:
identifier = Identifier(system="cardinal", value="xRay")
service_iterator = sdk.contact.filter_services_by_blocking(
ServiceFilters.by_identifiers_for_self([identifier])
)
if not service_iterator.has_next_blocking():
print("No matching services found")
while service_iterator.has_next_blocking():
service = service_iterator.next_blocking(1)[0]
pretty_print_service(service)
input("Press enter for next service")
let choice = -1
while (choice < 0 || choice >= 3) {
console.log("0. blood pressure")
console.log("1. heart rate")
console.log("2. x ray")
choice = parseInt((await readLn("Enter your choice: ")).trim())
}
let identifier: Identifier
switch (choice) {
case 0:
identifier = new Identifier({system: "cardinal", value: "bloodPressure"})
break
case 1:
identifier = new Identifier({system: "cardinal", value: "ecg"})
break
default:
identifier = new Identifier({system: "cardinal", value: "xRay"})
break
}
const serviceIterator = await sdk.contact.filterServicesBy(
ServiceFilters.byIdentifiersForSelf([identifier])
)
if (!(await serviceIterator.hasNext())) {
console.log("No matching services found")
}
while (await serviceIterator.hasNext()) {
const service = (await serviceIterator.next(1))[0]
prettyPrintService(service)
await readLn("Press enter for next service")
}
int choice = readChoiceFromUI();
Identifier identifier;
switch(choice) {
case 0:
identifier = Identifier(system: "cardinal", value: "bloodPressure");
case 1:
identifier = Identifier(system: "cardinal", value: "ecg");
case 2:
identifier = Identifier(system: "cardinal", value: "xRay");
default:
throw ArgumentError("Invalid choice");
}
final serviceIterator = await sdk.contact.filterServicesBy(
await ServiceFilters.byIdentifiersForSelf([identifier])
);
if (!(await serviceIterator.hasNext())) {
showErrorForNoContactsFound();
}
while (await serviceIterator.hasNext()) {
final service = (await serviceIterator.next(1)).first;
showServiceOnUI();
await readLn("Press enter for next service")
}
In this example, the filter method returns all the Services
that have the provided identifier in the identifiers
filter.