\n","children":[{"type":"text","text":""}]},{"type":"p","children":[{"type":"text","text":"RelationalAI is built on knowledge graphs, which rarely use null and boolean values. And yet, Rel, RelationAI’s declarative modeling language, has a "},{"type":"text","text":"Missing","code":true},{"type":"text","text":" data type to represent "},{"type":"text","text":"null","code":true},{"type":"text","text":" values, and a "},{"type":"text","text":"Bool","code":true},{"type":"text","text":" type to represent "},{"type":"text","text":"true","code":true},{"type":"text","text":" and "},{"type":"text","text":"false","code":true},{"type":"text","text":" boolean values."}]},{"type":"p","children":[{"type":"text","text":"Let's explore the role null and boolean values play in a dataset and learn when to use "},{"type":"text","text":"Missing","code":true},{"type":"text","text":" and "},{"type":"text","text":"Bool","code":true},{"type":"text","text":" types in Rel."}]},{"type":"h2","children":[{"type":"text","text":"Representing When Facts Are Not Present"}],"id":"representing-when-facts-are-not-present"},{"type":"p","children":[{"type":"text","text":"Consider a database of invoices for a company."}]},{"type":"p","children":[{"type":"text","text":"You might want to store purchase orders associated with an invoice. But not every client uses purchase orders, so you record those with a null value --- perhaps as "},{"type":"text","text":"NULL","code":true},{"type":"text","text":" in a SQL table or as "},{"type":"text","text":"null","code":true},{"type":"text","text":" in a JSON document. Maybe you need to track whether or not the invoice has been paid. You record that as a "},{"type":"text","text":"true","code":true},{"type":"text","text":" or "},{"type":"text","text":"false","code":true},{"type":"text","text":" boolean value."}]},{"type":"p","children":[{"type":"text","text":"The resulting table of invoices in a SQL database might look something like this:"}]},{"type":"mdxJsxFlowElement","children":[{"type":"text","text":""}],"name":"table","props":{"align":[],"tableRows":[{"tableCells":[{"value":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"id"}]}]}},{"value":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"purchase_order"}]}]}},{"value":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"paid"}]}]}}]},{"tableCells":[{"value":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"1"}]}]}},{"value":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"NULL"}]}]}},{"value":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"true"}]}]}}]},{"tableCells":[{"value":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"1"}]}]}},{"value":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"“PO-0006”"}]}]}},{"value":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"false"}]}]}}]}]}},{"type":"p","children":[{"type":"text","text":"What do "},{"type":"text","text":"NULL","code":true},{"type":"text","text":" and "},{"type":"text","text":"boolean","code":true},{"type":"text","text":" values have in common?"}]},{"type":"p","children":[{"type":"text","text":"Both concepts represent the presence, or lack thereof, of a fact."}]},{"type":"p","children":[{"type":"text","text":"NULL","code":true},{"type":"text","text":" represents the absence of a purchase order. "},{"type":"text","text":"True","code":true},{"type":"text","text":" and "},{"type":"text","text":"false","code":true},{"type":"text","text":" represent whether or not a payment has been received. The presence, or non-presence, of a fact determines which value is assigned."}]},{"type":"p","children":[{"type":"text","text":"The question is: if a fact is not present, does it need to be in your data?"}]},{"type":"h2","children":[{"type":"text","text":"Modeling: Missing and Boolean (Usually) Aren’t Necessary"}],"id":"modeling-missing-and-boolean-usually-aren-t-necessary"},{"type":"p","children":[{"type":"text","text":"In a knowledge graph, nodes representing entities in a model are related by edges representing the various relationships between those entities."}]},{"type":"p","children":[{"type":"text","text":"For example, an "},{"type":"text","text":"Invoice","code":true},{"type":"text","text":" entity can be related to a "},{"type":"text","text":"PurchaseOrder","code":true},{"type":"text","text":" entity via an edge labeled "},{"type":"text","text":"has_purchase_order","code":true},{"type":"text","text":", and a Payment entity via a "},{"type":"text","text":"has_payment","code":true},{"type":"text","text":" edge:"}]},{"type":"mdxJsxFlowElement","name":"ImgFig","children":[{"type":"text","text":""}],"props":{"src":"/blog/boolean-and-missing-what-are-they-good-for/knowledge-graph-example.png","alt":"Knowledge graph example","width":"100%"}},{"type":"p","children":[{"type":"text","text":"n a knowledge graph, you don’t need to store "},{"type":"text","text":"NUL","code":true},{"type":"text","text":"L values or keep track of "},{"type":"text","text":"true","code":true},{"type":"text","text":" and "},{"type":"text","text":"false","code":true},{"type":"text","text":". Missing data simply isn’t there. If an "},{"type":"text","text":"Invoice","code":true},{"type":"text","text":" has no "},{"type":"text","text":"PurchaseOrder","code":true},{"type":"text","text":", there’s no "},{"type":"text","text":"has_purchase_order","code":true},{"type":"text","text":" edge. If an "},{"type":"text","text":"Invoice","code":true},{"type":"text","text":" hasn’t been paid, there’s no "},{"type":"text","text":"has_payment","code":true},{"type":"text","text":" edge."}]},{"type":"p","children":[{"type":"text","text":"With so much emphasis on knowledge graphs, it may seem contradictory to have "},{"type":"text","text":"Missing","code":true},{"type":"text","text":" and "},{"type":"text","text":"Bool","code":true},{"type":"text","text":" values in Rel, but sometimes you really do need them."}]},{"type":"p","children":[{"type":"text","text":"For more information on modeling graphs, see "},{"type":"a","url":"https://docs.relational.ai/rel/concepts/graph-normal-form","title":null,"children":[{"type":"text","text":"Data Modeling: Graph Normal Form"}]},{"type":"text","text":"."}]},{"type":"h2","children":[{"type":"text","text":"Data Ingestion: Reconstructible Representations in Rel"}],"id":"data-ingestion-reconstructible-representations-in-rel"},{"type":"p","children":[{"type":"text","text":"When you ingest data into RelationalAI’s "},{"type":"a","url":"https://docs.relational.ai/rkgms/why-rkgs","title":null,"children":[{"type":"text","text":"Relational Knowledge Graph System (RKGS)"}]},{"type":"text","text":", you create a representation of that data in Rel."}]},{"type":"p","children":[{"type":"text","text":"Representations of data need to be high-fidelity. That is, you should be able to reconstruct the original data from the Rel representation. This means that Rel needs a way to represent null and boolean values."}]},{"type":"p","children":[{"type":"text","text":"For example, an invoice might be ingested from a JSON document:"}]},{"type":"code_block","lang":"javascript","value":"// json\n{\n \"id\": 1,\n \"purchase_order\": null,\n \"paid\": true\n}","children":[{"type":"text","text":""}]},{"type":"p","children":[{"type":"text","text":"In Rel, this JSON document gets represented as the following relation:"}]},{"type":"code_block","lang":"rel","value":"// Rel\n{\n (:id, 1);\n (:purchase_order, missing);\n (:paid, boolean_true);\n}","children":[{"type":"text","text":""}]},{"type":"p","children":[{"type":"text","text":"The "},{"type":"text","text":"missing","code":true},{"type":"text","text":" value is the only primitive value of the "},{"type":"text","text":"Missing","code":true},{"type":"text","text":" type. The "},{"type":"text","text":"Bool","code":true},{"type":"text","text":" type has two primitive values: "},{"type":"text","text":"boolean_true","code":true},{"type":"text","text":" and "},{"type":"text","text":"boolean_false","code":true},{"type":"text","text":"."}]},{"type":"p","children":[{"type":"text","text":"Having values of type "},{"type":"text","text":"Missing","code":true},{"type":"text","text":" and "},{"type":"text","text":"Bool","code":true},{"type":"text","text":" in Rel allows you to export relations as JSON, if needed. And you can accurately reconstruct data that has been ingested. But you usually won’t use "},{"type":"text","text":"Missing","code":true},{"type":"text","text":" and "},{"type":"text","text":"Bool","code":true},{"type":"text","text":" types in your models."}]}],"_content_source":{"queryId":"src/content/resources/boolean-and-missing-what-are-they-good-for.mdx","path":["resource","body"]}},"_content_source":{"queryId":"src/content/resources/boolean-and-missing-what-are-they-good-for.mdx","path":["resource"]}}},"errors":null,"query":"\n query resource($relativePath: String!) {\n resource(relativePath: $relativePath) {\n ... on Document {\n _sys {\n filename\n basename\n breadcrumbs\n path\n relativePath\n extension\n }\n id\n }\n ...ResourceParts\n }\n}\n \n fragment ResourceParts on Resource {\n __typename\n title\n description\n date\n image\n categories\n authors {\n __typename\n name\n link\n }\n seo {\n __typename\n keywords\n description\n image\n image_alt\n canonical_url\n author\n published\n modified\n language\n robots\n site_name\n content_type\n }\n body\n}\n ","variables":{"relativePath":"boolean-and-missing-what-are-they-good-for.mdx"}},"src/content/meta/meta.md":{"data":{"meta":{"_sys":{"filename":"meta","basename":"meta.md","breadcrumbs":["meta"],"path":"src/content/meta/meta.md","relativePath":"meta.md","extension":".md"},"id":"src/content/meta/meta.md","__typename":"Meta","banner":{"__typename":"MetaBanner","enabled":true,"content":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Check out "},{"type":"a","url":"/resources/highlights-of-relationalai-at-snowflake-data-cloud-summit-2024","title":"SF summit highlights","children":[{"type":"text","text":"highlights"}]},{"type":"text","text":" of RelationalAI at "},{"type":"text","text":"Snowflake's Data Cloud Summit 2024!","bold":true}]}],"_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","banner","content"]}},"_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","banner"]}},"header":{"__typename":"MetaHeader","links":[{"__typename":"MetaHeaderLinks","text":"Product","url":"/product","style":"default","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","header","links",0]}},{"__typename":"MetaHeaderLinks","text":"Company","url":"/company","style":"default","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","header","links",1]}},{"__typename":"MetaHeaderLinks","text":"Docs","url":"/docs","style":"default","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","header","links",2]}},{"__typename":"MetaHeaderLinks","text":"Resources","url":"/resources/all/1","style":"default","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","header","links",3]}},{"__typename":"MetaHeaderLinks","text":"Get Started","url":"/get-started","style":"cta","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","header","links",4]}}],"_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","header"]}},"footer":{"__typename":"MetaFooter","sections":[{"__typename":"MetaFooterSections","name":"Product","links":[{"__typename":"MetaFooterSectionsLinks","text":"Overview","url":"/product","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",0,"links",0]}},{"__typename":"MetaFooterSectionsLinks","text":"Use Cases","url":"/product#for-problems-that-matter","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",0,"links",1]}},{"__typename":"MetaFooterSectionsLinks","text":"Capabilities","url":"/product#a-new-toolset","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",0,"links",2]}}],"_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",0]}},{"__typename":"MetaFooterSections","name":"Resources","links":[{"__typename":"MetaFooterSectionsLinks","text":"Documentation","url":"/docs/getting_started","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",1,"links",0]}},{"__typename":"MetaFooterSectionsLinks","text":"News","url":"/resources/news/1","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",1,"links",1]}},{"__typename":"MetaFooterSectionsLinks","text":"Research","url":"/resources/research/1","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",1,"links",2]}},{"__typename":"MetaFooterSectionsLinks","text":"Releases","url":"/resources/releases/1","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",1,"links",3]}}],"_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",1]}},{"__typename":"MetaFooterSections","name":"About Us","links":[{"__typename":"MetaFooterSectionsLinks","text":"Our Company","url":"/company","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",2,"links",0]}},{"__typename":"MetaFooterSectionsLinks","text":"Contact Us","url":"/get-started","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",2,"links",1]}},{"__typename":"MetaFooterSectionsLinks","text":"Careers","url":"/careers","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",2,"links",2]}},{"__typename":"MetaFooterSectionsLinks","text":"Legal","url":"/legal","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",2,"links",3]}},{"__typename":"MetaFooterSectionsLinks","text":"GDPR","url":"/gdpr","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",2,"links",4]}},{"__typename":"MetaFooterSectionsLinks","text":"Security & Trust","url":"https://trust.relational.ai/","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",2,"links",5]}}],"_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","sections",2]}}],"socials":[{"__typename":"MetaFooterSocials","text":"GitHub","url":"https://github.com/RelationalAI","icon":"https://assets.tina.io/91d76337-e55d-4722-acb5-3106adb895b6/img/logos/github.png","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","socials",0]}},{"__typename":"MetaFooterSocials","text":"LinkedIn","url":"https://www.linkedin.com/company/relationalai/about","icon":"https://assets.tina.io/91d76337-e55d-4722-acb5-3106adb895b6/img/logos/linkedin.png","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","socials",1]}},{"__typename":"MetaFooterSocials","text":"Twitter","url":"https://twitter.com/relationalai","icon":"https://assets.tina.io/91d76337-e55d-4722-acb5-3106adb895b6/img/logos/twitter.png","_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer","socials",2]}}],"_content_source":{"queryId":"src/content/meta/meta.md","path":["meta","footer"]}},"_content_source":{"queryId":"src/content/meta/meta.md","path":["meta"]}}},"errors":null,"query":"\n query meta($relativePath: String!) {\n meta(relativePath: $relativePath) {\n ... on Document {\n _sys {\n filename\n basename\n breadcrumbs\n path\n relativePath\n extension\n }\n id\n }\n ...MetaParts\n }\n}\n \n fragment MetaParts on Meta {\n __typename\n banner {\n __typename\n enabled\n content\n }\n header {\n __typename\n links {\n __typename\n text\n url\n style\n }\n }\n footer {\n __typename\n sections {\n __typename\n name\n links {\n __typename\n text\n url\n }\n }\n socials {\n __typename\n text\n url\n icon\n }\n }\n}\n ","variables":{"relativePath":"./meta.md"}}};
globalThis.tina_info = tina;
})();
Boolean and Missing: What Are They Good For? · RelationalAI
Check out highlights of RelationalAI at Snowflake's Data Cloud Summit 2024!
RelationalAI is built on knowledge graphs, which rarely use null and boolean values. And yet, Rel, RelationAI’s declarative modeling language, has a Missing data type to represent null values, and a Bool type to represent true and false boolean values.
Let's explore the role null and boolean values play in a dataset and learn when to use Missing and Bool types in Rel.
Representing When Facts Are Not Present
Consider a database of invoices for a company.
You might want to store purchase orders associated with an invoice. But not every client uses purchase orders, so you record those with a null value --- perhaps as NULL in a SQL table or as null in a JSON document. Maybe you need to track whether or not the invoice has been paid. You record that as a true or false boolean value.
The resulting table of invoices in a SQL database might look something like this:
id
purchase_order
paid
1
NULL
true
1
“PO-0006”
false
What do NULL and boolean values have in common?
Both concepts represent the presence, or lack thereof, of a fact.
NULL represents the absence of a purchase order. True and false represent whether or not a payment has been received. The presence, or non-presence, of a fact determines which value is assigned.
The question is: if a fact is not present, does it need to be in your data?
Modeling: Missing and Boolean (Usually) Aren’t Necessary
In a knowledge graph, nodes representing entities in a model are related by edges representing the various relationships between those entities.
For example, an Invoice entity can be related to a PurchaseOrder entity via an edge labeled has_purchase_order, and a Payment entity via a has_payment edge:
n a knowledge graph, you don’t need to store NULL values or keep track of true and false. Missing data simply isn’t there. If an Invoice has no PurchaseOrder, there’s no has_purchase_order edge. If an Invoice hasn’t been paid, there’s no has_payment edge.
With so much emphasis on knowledge graphs, it may seem contradictory to have Missing and Bool values in Rel, but sometimes you really do need them.
Representations of data need to be high-fidelity. That is, you should be able to reconstruct the original data from the Rel representation. This means that Rel needs a way to represent null and boolean values.
For example, an invoice might be ingested from a JSON document:
The missing value is the only primitive value of the Missing type. The Bool type has two primitive values: boolean_true and boolean_false.
Having values of type Missing and Bool in Rel allows you to export relations as JSON, if needed. And you can accurately reconstruct data that has been ingested. But you usually won’t use Missing and Bool types in your models.