locked
Blood Glucose Averages RRS feed

  • Question

  •  

    We would like to see the HealthVault API allow for querying the data of HealthRecordItems in additional ways.  For example, when working with the BloodGlucose and BloodGlucoseMeasurement types, we would like to be able to request aggregate queries, where we can ask to get back information such as:

    Daily average of measurement property in a range of xx/xx/xxxx to yy/yy/yyyy

    Monthly average of measurement property in a range of xx/xx/xxxx to yy/yy/yyyy

    For types that could potentially have thousands of records, a variety of aggregate query options would be very beneficial.

    Wednesday, July 23, 2008 10:55 PM

Answers

  • I want to be sure I understand what you want a bit more.  When you talk about ranges are you talking about date ranges?  So a daily range would be something like 07/24/2008 to 07/25/2008?  Meaning everything on 7/24/2008, correct?  If that's what you are talking about, then we have that today.  Take a look at the HealthRecordFilter.EffectiveDateMin and HealthRecordItem.EffectiveDateMax filter options.

     

    As far as aggregation is concerned...  we give you the complete flexibiliy of the XSL language.  By using HealthRecordSearcher.GetTransformedItems(...) you can specify any XSL you want to be run on the result XML of your search.  To get a daily average for blood glucose you would have an XSL similar to the following.

    Code Snippet

     

    <xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

    xmlns:wc="urn:com.microsoft.wc.methods.response.GetThings"

    xmlns="urn:astm-org:CCR">

     

    <xsl:template match="/">

    <xsl:variable

    name="count"

    select="count(/response/wc:info/group/thing[type-id = '879e7c04-4e8a-4707-9ad3-b054df467ce4']/data-xml/blood-glucose/value/mmolPerL)"/>

     

    <xsl:variable

    name="sum"

    select="sum(/response/wc:info/group/thing[type-id = '879e7c04-4e8a-4707-9ad3-b054df467ce4']/data-xml/blood-glucose/value/mmolPerL)"/>

     

    <xsl:choose>

    <xsl:when test="$sum != 0 and $count != 0">

    <xsl:value-of select="$sum div $count"/>

    </< FONT>xsl:when>

    <xsl:otherwise>

    <xsl:value-of select="0"/>

    </< FONT>xsl:otherwise>

    </< FONT>xsl:choose>

    </< FONT>xsl:template>

    </< FONT>xsl:stylesheet>

     

     

    This transform does three things.  It selects into the variable "count" the number of instances of blood-glucose things that have mmolPerL set. It selects into the variable "sum" the summation of those values.  Then it produces the average as long as both "count" and "sum" are not zero, else it returns zero.

     

    Now to call with the appropriate filter. Lets assume that "record" has already be set to the HealthRecordInfo for the person and "xsl" is a string representation above (could have been loaded from a file or hardcoded or whatever).

     

    Code Snippet

    HealthRecordSearcher searcher = record.CreateSearcher();

     

    HealthRecordFilter filter = new HealthRecordFilter(BloodGlucose.TypeId);

    filter.EffectiveDateMin = new DateTime(2008, 7, 24);

    filter.EffectiveDateMax = new DateTime(2008, 7, 25);

    searcher.Filters.Add(filter);

     

    string bloodGlucoseAverageString = searcher.GetTransformedItems(xsl);

     

    int bloodGlucoseAverage = 0;

    Int32.TryParse(bloodGlucoseAverageString, out bloodGlucoseAverage);

     

     

    Here you setup your query just like you would any other query to get data from a HealthVault record.  The main difference is that you call GetTransformedItems(...) rather than GetMatchingItems().  The parameter to the GetTransformedItems call is the XSL you want the server to run. Note, there are some limitations on the XSL.  You can't have embeded scripts, use custom extensions, etc. for security reasons. 

     

    This gives you a lot more power to customize how you want the data returned than if we were to provide you with some very specific aggregators.

     

    Jeff Jones

     

    Thursday, July 24, 2008 4:13 PM
  • That would be interesting for us to consider. Can you go to the healthvault page on connect.microsoft.com and enter it as a suggestion? That will make sure it gets to the right people and give you a way to track it.

    Thursday, July 24, 2008 4:20 PM

All replies

  • I want to be sure I understand what you want a bit more.  When you talk about ranges are you talking about date ranges?  So a daily range would be something like 07/24/2008 to 07/25/2008?  Meaning everything on 7/24/2008, correct?  If that's what you are talking about, then we have that today.  Take a look at the HealthRecordFilter.EffectiveDateMin and HealthRecordItem.EffectiveDateMax filter options.

     

    As far as aggregation is concerned...  we give you the complete flexibiliy of the XSL language.  By using HealthRecordSearcher.GetTransformedItems(...) you can specify any XSL you want to be run on the result XML of your search.  To get a daily average for blood glucose you would have an XSL similar to the following.

    Code Snippet

     

    <xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

    xmlns:wc="urn:com.microsoft.wc.methods.response.GetThings"

    xmlns="urn:astm-org:CCR">

     

    <xsl:template match="/">

    <xsl:variable

    name="count"

    select="count(/response/wc:info/group/thing[type-id = '879e7c04-4e8a-4707-9ad3-b054df467ce4']/data-xml/blood-glucose/value/mmolPerL)"/>

     

    <xsl:variable

    name="sum"

    select="sum(/response/wc:info/group/thing[type-id = '879e7c04-4e8a-4707-9ad3-b054df467ce4']/data-xml/blood-glucose/value/mmolPerL)"/>

     

    <xsl:choose>

    <xsl:when test="$sum != 0 and $count != 0">

    <xsl:value-of select="$sum div $count"/>

    </< FONT>xsl:when>

    <xsl:otherwise>

    <xsl:value-of select="0"/>

    </< FONT>xsl:otherwise>

    </< FONT>xsl:choose>

    </< FONT>xsl:template>

    </< FONT>xsl:stylesheet>

     

     

    This transform does three things.  It selects into the variable "count" the number of instances of blood-glucose things that have mmolPerL set. It selects into the variable "sum" the summation of those values.  Then it produces the average as long as both "count" and "sum" are not zero, else it returns zero.

     

    Now to call with the appropriate filter. Lets assume that "record" has already be set to the HealthRecordInfo for the person and "xsl" is a string representation above (could have been loaded from a file or hardcoded or whatever).

     

    Code Snippet

    HealthRecordSearcher searcher = record.CreateSearcher();

     

    HealthRecordFilter filter = new HealthRecordFilter(BloodGlucose.TypeId);

    filter.EffectiveDateMin = new DateTime(2008, 7, 24);

    filter.EffectiveDateMax = new DateTime(2008, 7, 25);

    searcher.Filters.Add(filter);

     

    string bloodGlucoseAverageString = searcher.GetTransformedItems(xsl);

     

    int bloodGlucoseAverage = 0;

    Int32.TryParse(bloodGlucoseAverageString, out bloodGlucoseAverage);

     

     

    Here you setup your query just like you would any other query to get data from a HealthVault record.  The main difference is that you call GetTransformedItems(...) rather than GetMatchingItems().  The parameter to the GetTransformedItems call is the XSL you want the server to run. Note, there are some limitations on the XSL.  You can't have embeded scripts, use custom extensions, etc. for security reasons. 

     

    This gives you a lot more power to customize how you want the data returned than if we were to provide you with some very specific aggregators.

     

    Jeff Jones

     

    Thursday, July 24, 2008 4:13 PM
  • That would be interesting for us to consider. Can you go to the healthvault page on connect.microsoft.com and enter it as a suggestion? That will make sure it gets to the right people and give you a way to track it.

    Thursday, July 24, 2008 4:20 PM