brocade.io icon indicating copy to clipboard operation
brocade.io copied to clipboard

Feature: Nutrition Facts

Open ferrisoxide opened this issue 5 years ago • 4 comments

Present nutrition-related properties in a sensible collection, as per the original Datakick style:

Screen Shot 2020-03-25 at 9 14 40 pm

NB "Percent of daily values" text at the bottom is derived /assumed and not part of the stored properties values.

NB Default units are not present in the data (and have to be assumed) - e.g. 'Trans Fat' (or trans_fat) is measured in g, whereas Cholesterol is measured in mg. In neither case is the unit stored in the data, with the properties stored as { "trans_fat":0.0, "cholesterol":0 }.

NB Some values are grouped and tallied, e.g. Saturated Fat, Trans Fat, etc are grouped and tallied as 'Total Fats'. The total value is present in the stored properties (as fat) - see * Example JSON Data* below.

NB Total calories and Calories from Fat are reported separately. This data is present in the stored properties (as fat) - see * Example JSON Data* below.

Example JSON Data

{"gtin14":"00000000079983","brand_name":"Trader Joe's","name":"Pistachios - Dry Roasted & Salted","size":"16 oz (1 lb) 454 g","ingredients":"Pistachios, Salt\r\n\r\nFACILITY PROCESSES OTHER TREE NUTS","serving_size":"1/4 cup nuts without shells (30 g / about 1/2 cup with shells)","servings_per_container":"about 8","calories":180,"fat_calories":120,"fat":14.0,"saturated_fat":1.5,"trans_fat":0.0,"polyunsaturated_fat":2.5,"monounsaturated_fat":10.0,"cholesterol":0,"sodium":160,"carbohydrate":9,"fiber":3,"sugars":3,"protein":6,"images":[]}

ferrisoxide avatar Mar 25 '20 11:03 ferrisoxide

DEV NOTE

Might be worth look at passing queries through to Open Food Facts:

https://github.com/openfoodfacts/openfoodfacts-ruby

ferrisoxide avatar Feb 10 '23 02:02 ferrisoxide

Looks like openfoodfacts use this as a basic RDF structure:

food.zip

NB The URL for the schema seems to have disappeared, but can be found via the Wayback Machine

We can probably convert from the RDF format to JSON-LD fairly easily, e.g. using https://issemantic.net/rdf-converter:

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
                xmlns:food="http://data.lirmm.fr/ontologies/food#"
                xmlns:dcterms="http://purl.org/dc/terms/"
                xmlns:dc="http://purl.org/dc/elements/1.1/"
                xmlns:void="http://rdfs.org/ns/void#"
                xmlns:owl="http://www.w3.org/2002/07/owl#"
                xmlns:foaf="http://xmlns.com/foaf/0.1/">

<rdf:Description rdf:about="http://world-en.openfoodfacts.org/product/0000000000000207025004/andre" rdf:type="http://data.lirmm.fr/ontologies/food#FoodProduct">
        <food:code>0000000000000207025004</food:code>
        <food:name>Andrè</food:name>
        <food:IngredientListAsText></food:IngredientListAsText>
        <food:carbohydratesPer100g>65</food:carbohydratesPer100g>
        <food:energyPer100g>690</food:energyPer100g>
        <food:energyKcalPer100g>165</food:energyKcalPer100g>
        <food:fatPer100g>2</food:fatPer100g>
        <food:fiberPer100g>3</food:fiberPer100g>
        <food:proteinsPer100g>1.5</food:proteinsPer100g>
        <food:saturatedFatPer100g>2</food:saturatedFatPer100g>
        <food:sugarsPer100g>12.6</food:sugarsPer100g>
</rdf:Description>
</rdf:RDF>

becomes

[
  {
    "@id": "http://world-en.openfoodfacts.org/product/0000000000000207025004/andre",
    "@type": [
      "http://data.lirmm.fr/ontologies/food#FoodProduct"
    ],
    "http://data.lirmm.fr/ontologies/food#IngredientListAsText": [
      {
        "@value": ""
      }
    ],
    "http://data.lirmm.fr/ontologies/food#carbohydratesPer100g": [
      {
        "@value": "65"
      }
    ],
    "http://data.lirmm.fr/ontologies/food#code": [
      {
        "@value": "0000000000000207025004"
      }
    ],
    "http://data.lirmm.fr/ontologies/food#energyKcalPer100g": [
      {
        "@value": "165"
      }
    ],
    "http://data.lirmm.fr/ontologies/food#energyPer100g": [
      {
        "@value": "690"
      }
    ],
    "http://data.lirmm.fr/ontologies/food#fatPer100g": [
      {
        "@value": "2"
      }
    ],
    "http://data.lirmm.fr/ontologies/food#fiberPer100g": [
      {
        "@value": "3"
      }
    ],
    "http://data.lirmm.fr/ontologies/food#name": [
      {
        "@value": "Andrè"
      }
    ],
    "http://data.lirmm.fr/ontologies/food#proteinsPer100g": [
      {
        "@value": "1.5"
      }
    ],
    "http://data.lirmm.fr/ontologies/food#saturatedFatPer100g": [
      {
        "@value": "2"
      }
    ],
    "http://data.lirmm.fr/ontologies/food#sugarsPer100g": [
      {
        "@value": "12.6"
      }
    ]
  }
]

Though it looks like the structure of the JSON retrieved directly from OpenFoodFacts is slightly different, e.g. "sugarsPer100g" in the converted RDF maps to "sugars_100g" in the JSON (see https://world.openfoodfacts.org/api/v0/product/737628064502.json for an example).

We will need to pick a schema - I'm leaning towards the RDF-derived one at present.

ferrisoxide avatar Feb 14 '23 12:02 ferrisoxide

Per brief discussion with people from OFF, it looks like the RDF model hasn't been worked on in ~ 10 years. JSON is the preferred data transfer model, but without a specific schema it'll be awkward fitting it into a JSON-LD graph.

The information re "structured data" on the OFF website is probably out of date, but does have some interesting links - including references back to schema.org:

https://wiki.openfoodfacts.org/Structured_Data

There is some good advice on how to make use of the data from the OFF site:

https://wiki.openfoodfacts.org/Reusing_Open_Food_Facts_Data

We also might be able to make use of the OFF taxonomies to provide translations of content, something we haven't even thought about up to this point:

https://github.com/openfoodfacts/openfoodfacts-server/tree/main/taxonomies

ferrisoxide avatar Feb 15 '23 00:02 ferrisoxide