0

I am trying to write a SPARQL query which will return a set of patient identifier codes (?Crid) which have associated with them a specific diagnosis code (?ICD9) and DO NOT have associated with them a specific medication AND which have an order date (?OrderDate) prior to their recruitment date (?RecruitDate). I have incorporated the OBIB ontology into my graph.

Here is what I have so far (a bit simplified and with a few steps through the graph omitted for readability/sensitivity):

SELECT DISTINCT ?Crid WHERE 
{?Crid a obib:CRID .

#-- Return CRIDs with a diagnosis
?Crid obib:hasPart ?ICD9 .
?ICD9 a obib:diagnosis .

#-- Return CRIDs with a medical prescription record
?Crid obib:hasPart ?medRecord .
?medRecord a obib:medicalRecord .

#-- Return CRIDs with an order date
?medRecord obib:hasPart ?OrderDate .
?OrderDate a obib:dateOfDataEntry .

#-- Return CRIDs with a recruitment date
?Crid obib:hasPart ?FormFilling .
?FormFilling a obib:formFilling .
?RecruitDate obib:isAbout ?FormFilling .
?RecruitDate a obib:dateOfDataEntry .

#-- Filter results for specific ICD9 codes
FILTER (?ICD9 = '1')

#-- Subtract Results with Certain Medication and Order Date Prior to Recruitment
#-- This is the part that I think is giving me a problem
MINUS {
    FILTER (regex (?medRecord, "medication_1", "i"))
    FILTER (?RecruitDate-?OrderDate < "P0D"^^xsd:dayTimeDuration)
      }
}

My gut feeling is that I am not using MINUS correctly. This query returns mostly the right results: I am expecting 10 results and it is returning 12. The extraneous 2 results did take "medication_1" and have order dates before their recruitment dates, so I do not want them to be included in the set.

In case it matters, I am using a Stardog endpoint to run this query and to store my graph data.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
hayfreed
  • 525
  • 7
  • 21

1 Answers1

1

Instead of

#-- Subtract Results with Certain Medication and Order Date Prior to Recruitment
#-- This is the part that I think is giving me a problem
MINUS {
    FILTER (regex (?medRecord, "medication_1", "i"))
    FILTER (?RecruitDate-?OrderDate < "P0D"^^xsd:dayTimeDuration)
      }
}

I'd probably just write this without MINUS as:

FILTER (!regex(?medRecord, "medication_1", "i"))
FILTER (?RecruitDate-?OrderDate >= "P0D"^^xsd:dayTimeDuration)

I'd also probably consider whether REGEX is the right tool here (would a simple string comparison work?), but that's a different issue.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • Thanks for your response. I think the problem with this approach is that it excludes patients who HAVE taken "medication_1", but have an Order Date that is after their Recruitment Date. In order for a patient to be excluded, they need to have ordered "medication_1" BEFORE their recruitment date. – hayfreed Feb 10 '17 at 18:00
  • 1
    @hayfreed But in any case, MINUS itself is a graph pattern that returns a resultset - in your example it's always empty since you haven't selected any triple pattern inside the MINUS clause. – UninformedUser Feb 10 '17 at 18:25