Honeydew entities can model many different data structures. However, it is very common in relational modeling
to separate entities to facts and dimensions:
Dimensions provide descriptive information for measurements. Dimensions typically represent business entities
(such as a user, a product or a place), and include many properties for each instance. For example, a customer dimension
will include per-customer information such as age or geography. In a star or snowflake schemas, dimensions are typically
the leafs.
Facts typically represent measurable events (i.e. transactions, website visits, etc). They typically include a time field
and reference related dimensions (i.e. the transacting or visiting user) via foreign keys. In a star schema, the fact is
the center of a star.
In a schema that has multiple facts (and thus multiple stars or snowflake schemas combined), dimension that more
than more than one fact refers to are called Shared Dimensions.The shared (also called conformed) dimension has the same meaning to every fact with which it relates.For example, a user entity might appear in different facts describing things the user has done:
Honeydew automatically detects shared dimensions when more than one fact has a relationship to them.There is no configuration required. Honeydew will create optimized queries that conform data to the shared
dimension.
Honeydew never performs a fact-to-fact join on a shared dimension key, as that results in a
chasm trap heavy query.When calculating metrics on a shared
dimensions (like logins and visits count per user), Honeydew will calculate them separately and only join once
aggregated. That performance optimization is applied automatically.
In more complex schemas where fact tables refer to other fact tables, more than one relationship path can be defined.For example, can have a schema with two facts and a shared dimension:
A customer shared dimension details information per customer.
A orders fact entity has per-order data, and has a relation to the ordering customer.
A lineitem fact entity has the line items for each order and has a direct relationship to the ordering customer.
In that case, there are two ways to relate lineitem and customer:
Join directly lineitem and customer on lineitem.customer_id = customer.id
Join lineitem to orders on order_id and them join orders to customers on orders.customer_id = customer.id
When there is more than one way to connected a shared dimension Honeydew requires a direct relationship to be defined.
Honeydew will always join via the direct relationship when multiple relationship paths are possible.In the example above, Honeydew will join lineitem and customer directly when looking at line items of a customer.
When multiple paths are possible to connect a shared dimension, but there is no direct relation, then Honeydew
will not be able to resolve a path. A direct relationship must be added.
When there are multiple paths to a shared dimension required in a query, and none of those paths is a direct connection, Honeydew will fail to compile.Must create a direct connection for each entity to the shared dimension whenever multiple paths present.Can use calculated attributes to copy join keys if are missing. For example if:
Have a lineitem entity that relates to both customer and supplier.
Both customer and supplier have a shared dimension called nation.
Then for lineitem would not know which nation to prefer when counting revenue by nation.To resolve this situation:
Create a calculated attribute in lineitem that equals to the preferred nation (for example that equals to customer.c_nationkey).
Connect that calculated attribute directly to the shared nation entity.
A common use case with shared dimensions is querying one fact based on information from another fact with a connected shared dimension.For example, would want to build a metric that counts the visits of all users that had a login last month.Since there is no direct connection between visits and logins to join on, need to go through the shared user in the users entity
that takes data from the logins fact, so it can be used later on when joining users with visits.
Connected through a single shared dimension: users
Build the following metric:
count_visits_of_recently_logged_in_users =-- Count visits for users who also had logins in the last 30 daysvisits.count FILTER( -- Did the visiting user had logins over the last 30 days? WHERE ( -- Count logins logins.count -- Over last 30 days FILTER(WHERE logins.time >= CURRENT_DATE() - 30) -- For the shared user GROUP BY (users.user_id) ) > 0)
The internal metric on logins has a GROUP BY (users.id) qualifier that tells it to be calculated per user.Since user is a shared dimension between logins and visits, the result can be applied to a metric in visits.Note that if there are multiple shared dimensions, can connect through more than one.
Break to steps with a calculated attribute in the shared dimension
Use a calculated attribute when the connection between facts goes through a single shared dimension, and there is no dynamic calculation.In that case, can built a simpler single fact metric that uses that calculated attribute.To implement the question above with a calculated attribute approach:
Build a calculated attribute in the users shared entity named logins_last_month defined as
This counts per user the logins (assuming logins has a count metric) in the last month (assuming a time attribute), at the granularity
of a user (since the calculated attribute is part of the user entity).
See also how metrics behave in calculated attributes.
Build a metric in visits called count_visits_of_recently_logged_in_users defined as
This is a reusable metric based on data from two facts, counting first at the login fact granularity (logins last month)
and then at the visit fact granularity (visits of users that logged in last month).
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Honeydew Documentation","colors":{"primary":"#abcb1a","light":"#CBE74A","dark":"#9cb918"},"logo":{"light":"https://mintcdn.com/honeydew/FY_ZgBcPUZJ2-No3/logo/logo.svg?fit=max\u0026auto=format\u0026n=FY_ZgBcPUZJ2-No3\u0026q=85\u0026s=10dbf238c7bdb5bb1ee94e85eea8049f","dark":"https://mintcdn.com/honeydew/FY_ZgBcPUZJ2-No3/logo/logo-white.svg?fit=max\u0026auto=format\u0026n=FY_ZgBcPUZJ2-No3\u0026q=85\u0026s=c774c9340ba4f0a8828b7ad8aa1e4179","href":"https://honeydew.ai"},"favicon":"https://mintcdn.com/honeydew/mXl3IrOWJ_NESw09/favicon.png?fit=max\u0026auto=format\u0026n=mXl3IrOWJ_NESw09\u0026q=85\u0026s=4b76e0217dbafaa5c1b88b130a5e62c4","navbar":{"links":[{"href":"https://app.honeydew.cloud/signup","label":"Sign Up"},{"href":"https://app.honeydew.cloud/","label":"Login"},{"href":"https://honeydew.ai","label":"Website"}],"primary":{"type":"button","label":"Book a Demo","href":"https://honeydew.ai/get-started/"}},"footer":{"socials":{"twitter":"https://twitter.com/honeydewai","linkedin":"https://www.linkedin.com/company/honeydewai","github":"https://github.com/honeydew-ai"}},"integrations":{"ga4":{"measurementId":"G-3FG56HVDQ6"},"gtm":{"tagId":"GTM-MNTHZF6"},"hotjar":{"hjid":"3749326","hjsv":"6"},"segment":{"key":"SPDgvdM9OoZSCirKWUQj58GrrjBEzOoE"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"honeydew","hasAudioNarration":false,"actualSubdomain":"honeydew","customDomains":["honeydew.ai"],"gitSource":{"type":"github","owner":"honeydew-ai","repo":"docs","deployBranch":"main","contentDirectory":"content","isPrivate":false,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6aeb09fbe84fb046db8b74d1","collectionId":"bd93d249-2ab8-4a00-9172-b288e5de6540","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6aeb09fbe84fb046db8b74d1"},"feedback":{"thumbs":true},"entitlements":{},"buildId":"6aeb09fbe84fb046db8b74d1","clientVersion":"0.0.4067","searchFilterCounts":[{"language":"default","tag":"Integrations","count":48},{"language":"default","tag":"Modeling Reference","count":30},{"language":"default","tag":"BI Tools","count":19},{"language":"default","tag":"Management","count":17},{"language":"default","tag":"Security","count":11},{"language":"default","tag":"Recipes","count":10},{"language":"default","tag":"Advanced Modeling","count":8},{"language":"default","tag":"Authentication","count":7},{"language":"default","tag":"Governance","count":7},{"language":"default","tag":"Context Layer","count":7}]},"assistantConfig":{},"basePath":"/docs","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"advanced-modeling/shared-dimensions","slug":"/advanced-modeling/shared-dimensions","pageMetadata":{"title":"Multiple Facts and Shared Dimensions","description":null,"href":"/advanced-modeling/shared-dimensions"},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Tip,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Tip)_missingMdxReference(`Tip`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(Heading,{level:`2`,id:`introduction`,children:`Introduction`}),`\n`,_jsxs(_components.p,{children:[`Honeydew entities can model many different data structures. However, it is very common in relational modeling\nto separate entities to `,_jsx(_components.em,{children:`facts`}),` and `,_jsx(_components.em,{children:`dimensions`}),`:`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.em,{children:`Dimensions`}),` provide descriptive information for measurements. Dimensions typically represent business entities\n(such as a user, a product or a place), and include many properties for each instance. For example, a customer dimension\nwill include per-customer information such as age or geography. In a star or snowflake schemas, dimensions are typically\nthe leafs.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.em,{children:`Facts`}),` typically represent measurable events (i.e. transactions, website visits, etc). They typically include a time field\nand reference related dimensions (i.e. the transacting or visiting user) via foreign keys. In a star schema, the fact is\nthe center of a star.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`In a schema that has multiple facts (and thus multiple stars or snowflake schemas combined), dimension that more\nthan more than one fact refers to are called `,_jsx(_components.strong,{children:`Shared Dimensions`}),`.`]}),`\n`,_jsx(_components.p,{children:`The shared (also called conformed) dimension has the same meaning to every fact with which it relates.`}),`\n`,_jsxs(_components.p,{children:[`For example, a `,_jsx(_components.code,{children:`user`}),` entity might appear in different facts describing things the user has done:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`logins`}),` fact table describing application login events`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`visits`}),` fact table describing website visits events`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`building-shared-dimensions`,children:`Building Shared Dimensions`}),`\n`,_jsxs(_components.p,{children:[`Honeydew `,_jsx(_components.strong,{children:`automatically detects shared dimensions`}),` when more than one fact has a relationship to them.`]}),`\n`,_jsx(_components.p,{children:`There is no configuration required. Honeydew will create optimized queries that conform data to the shared\ndimension.`}),`\n`,_jsxs(Tip,{children:[_jsxs(_components.p,{children:[`Honeydew never performs a fact-to-fact join on a shared dimension key, as that results in a\n`,_jsx(_components.a,{href:`/advanced-modeling/mixing-granularities#chasm-trap`,children:`chasm trap`}),` heavy query.`]}),_jsx(_components.p,{children:`When calculating metrics on a shared\ndimensions (like logins and visits count per user), Honeydew will calculate them separately and only join once\naggregated. That performance optimization is applied automatically.`})]}),`\n`,_jsx(Heading,{level:`3`,id:`multiple-paths-to-shared-dimensions`,children:`Multiple Paths to Shared Dimensions`}),`\n`,_jsx(_components.p,{children:`In more complex schemas where fact tables refer to other fact tables, more than one relationship path can be defined.`}),`\n`,_jsx(_components.p,{children:`For example, can have a schema with two facts and a shared dimension:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`A `,_jsx(_components.code,{children:`customer`}),` shared dimension details information per customer.`]}),`\n`,_jsxs(_components.li,{children:[`A `,_jsx(_components.code,{children:`orders`}),` fact entity has per-order data, and has a relation to the ordering customer.`]}),`\n`,_jsxs(_components.li,{children:[`A `,_jsx(_components.code,{children:`lineitem`}),` fact entity has the line items for each order and has a direct relationship to the ordering customer.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`In that case, there are two ways to relate `,_jsx(_components.code,{children:`lineitem`}),` and `,_jsx(_components.code,{children:`customer`}),`:`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Join directly `,_jsx(_components.code,{children:`lineitem`}),` and `,_jsx(_components.code,{children:`customer`}),` on `,_jsx(_components.code,{children:`lineitem.customer_id = customer.id`})]}),`\n`,_jsxs(_components.li,{children:[`Join `,_jsx(_components.code,{children:`lineitem`}),` to `,_jsx(_components.code,{children:`orders`}),` on `,_jsx(_components.code,{children:`order_id`}),` and them join orders to customers on `,_jsx(_components.code,{children:`orders.customer_id = customer.id`})]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`When there is more than one way to connected a shared dimension Honeydew requires a `,_jsx(_components.em,{children:`direct relationship`}),` to be defined.`]}),`\n`,_jsxs(Tip,{children:[_jsx(_components.p,{children:`Honeydew will always join via the direct relationship when multiple relationship paths are possible.`}),_jsxs(_components.p,{children:[`In the example above, Honeydew will join `,_jsx(_components.code,{children:`lineitem`}),` and `,_jsx(_components.code,{children:`customer`}),` directly when looking at line items of a customer.`]})]}),`\n`,_jsx(_components.p,{children:`When multiple paths are possible to connect a shared dimension, but there is no direct relation, then Honeydew\nwill not be able to resolve a path. A direct relationship must be added.`}),`\n`,_jsxs(Warning,{children:[_jsx(_components.p,{children:`When there are multiple paths to a shared dimension required in a query, and none of those paths is a direct connection, Honeydew will fail to compile.`}),_jsx(_components.p,{children:`Must create a direct connection for each entity to the shared dimension whenever multiple paths present.`}),_jsxs(_components.p,{children:[`Can use `,_jsx(_components.a,{href:`/calculations/attributes`,children:`calculated attributes`}),` to copy join keys if are missing. For example if:`]}),_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Have a `,_jsx(_components.code,{children:`lineitem`}),` entity that relates to both `,_jsx(_components.code,{children:`customer`}),` and `,_jsx(_components.code,{children:`supplier`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Both `,_jsx(_components.code,{children:`customer`}),` and `,_jsx(_components.code,{children:`supplier`}),` have a shared dimension called `,_jsx(_components.code,{children:`nation`}),`.`]}),`\n`]}),_jsxs(_components.p,{children:[`Then for `,_jsx(_components.code,{children:`lineitem`}),` would not know which `,_jsx(_components.code,{children:`nation`}),` to prefer when counting revenue by nation.`]}),_jsx(_components.p,{children:`To resolve this situation:`}),_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Create a calculated attribute in `,_jsx(_components.code,{children:`lineitem`}),` that equals to the preferred nation (for example that equals to `,_jsx(_components.code,{children:`customer.c_nationkey`}),`).`]}),`\n`,_jsxs(_components.li,{children:[`Connect that calculated attribute directly to the shared `,_jsx(_components.code,{children:`nation`}),` entity.`]}),`\n`]})]}),`\n`,_jsx(Heading,{level:`2`,id:`metrics-that-combine-multiple-facts`,children:`Metrics that combine multiple facts`}),`\n`,_jsx(_components.p,{children:`A common use case with shared dimensions is querying one fact based on information from another fact with a connected shared dimension.`}),`\n`,_jsx(_components.p,{children:`For example, would want to build a metric that counts the visits of all users that had a login last month.`}),`\n`,_jsxs(_components.p,{children:[`Since there is no direct connection between visits and logins to join on, need to go through the shared user in the `,_jsx(_components.code,{children:`users`}),` entity\nthat takes data from the `,_jsx(_components.code,{children:`logins`}),` fact, so it can be used later on when joining users with `,_jsx(_components.code,{children:`visits`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`connect-metrics-through-a-shared-dimension`,children:`Connect metrics through a shared dimension`}),`\n`,_jsx(_components.p,{children:`Given the following schema:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Two facts: `,_jsx(_components.code,{children:`logins`}),` and `,_jsx(_components.code,{children:`visits`})]}),`\n`,_jsxs(_components.li,{children:[`Connected through a single shared dimension: `,_jsx(_components.code,{children:`users`})]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Build the following metric:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`12`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`12`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`count_visits_of_recently_logged_in_users `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`-- Count visits for users who also had logins in the last 30 days`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`visits`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`count`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FILTER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` -- Did the visiting user had logins over the last 30 days?`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` WHERE`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` -- Count logins`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` logins`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`count`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` -- Over last 30 days`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FILTER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WHERE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` logins`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`time`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` >=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CURRENT_DATE() `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`-`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 30`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` -- For the shared user`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` GROUP BY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`users`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`user_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsxs(Tip,{children:[_jsxs(_components.p,{children:[`The internal metric on `,_jsx(_components.code,{children:`logins`}),` has a `,_jsx(_components.code,{children:`GROUP BY (users.id)`}),` qualifier that tells it to be calculated per user.`]}),_jsxs(_components.p,{children:[`Since user is a shared dimension between `,_jsx(_components.code,{children:`logins`}),` and `,_jsx(_components.code,{children:`visits`}),`, the result can be applied to a metric in visits.`]}),_jsx(_components.p,{children:`Note that if there are multiple shared dimensions, can connect through more than one.`})]}),`\n`,_jsx(Heading,{level:`3`,id:`break-to-steps-with-a-calculated-attribute-in-the-shared-dimension`,children:`Break to steps with a calculated attribute in the shared dimension`}),`\n`,_jsx(_components.p,{children:`Use a calculated attribute when the connection between facts goes through a single shared dimension, and there is no dynamic calculation.`}),`\n`,_jsx(_components.p,{children:`In that case, can built a simpler single fact metric that uses that calculated attribute.`}),`\n`,_jsx(_components.p,{children:`To implement the question above with a calculated attribute approach:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[`Build a `,_jsx(_components.strong,{children:`calculated attribute`}),` in the `,_jsx(_components.code,{children:`users`}),` shared entity named `,_jsx(_components.code,{children:`logins_last_month`}),` defined as`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`logins`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`count`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FILTER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WHERE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` logins`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`time`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` >=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CURRENT_DATE() `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`-`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 30`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`This counts per user the logins (assuming logins has a `,_jsx(_components.code,{children:`count`}),` metric) in the last month (assuming a `,_jsx(_components.code,{children:`time`}),` attribute), at the granularity\nof a user (since the calculated attribute is part of the user entity).\nSee also `,_jsx(_components.a,{href:`/calculations/metrics#use-a-metric-or-aggregation-as-a-calculated-attribute`,children:`how metrics behave in calculated attributes`}),`.`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[`Build a `,_jsx(_components.strong,{children:`metric`}),` in `,_jsx(_components.code,{children:`visits`}),` called `,_jsx(_components.code,{children:`count_visits_of_recently_logged_in_users`}),` defined as`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`sql`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`sql`,children:_jsxs(_components.code,{language:`sql`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`visits`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`count`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` FILTER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`WHERE`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` users`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`logins_last_month`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` >`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`This is a reusable metric based on data from two facts, counting first at the login fact granularity (logins last month)\nand then at the visit fact granularity (visits of users that logged in last month).`}),`\n`]}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Multiple Facts and Shared Dimensions","description":null,"href":"/advanced-modeling/shared-dimensions"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Introduction","slug":"introduction","depth":2,"children":[]},{"title":"Building Shared Dimensions","slug":"building-shared-dimensions","depth":2,"children":[{"title":"Multiple Paths to Shared Dimensions","slug":"multiple-paths-to-shared-dimensions","depth":3,"children":[]}]},{"title":"Metrics that combine multiple facts","slug":"metrics-that-combine-multiple-facts","depth":2,"children":[{"title":"Connect metrics through a shared dimension","slug":"connect-metrics-through-a-shared-dimension","depth":3,"children":[]},{"title":"Break to steps with a calculated attribute in the shared dimension","slug":"break-to-steps-with-a-calculated-attribute-in-the-shared-dimension","depth":3,"children":[]}]}],"codeExamples":{}},"jsLinks":["/docs/_mintlify/custom/honeydew/82b3c90683bc6a9d/script.js"],"subdomain":"honeydew","siteName":"Honeydew Documentation","title":"Multiple Facts and Shared Dimensions - Honeydew Documentation","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-29T12:57:32.099Z","originalFileLocation":"advanced-modeling/shared-dimensions.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"application-name\" content=\"Honeydew Documentation\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Multiple Facts and Shared Dimensions - Honeydew Documentation\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Honeydew Documentation\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://honeydew.ai/docs/advanced-modeling/shared-dimensions\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://honeydew.mintlify.app/_mintlify/api/og/v2?division=Advanced+Modeling\u0026amp;title=Multiple+Facts+and+Shared+Dimensions\u0026amp;theme=0b845200c1ca80fd78144b6a\u0026amp;signature=f5dfeaa1f51ae99199b7a857cf7e22e1674627c61edf5db5fd093fa45f8be5b6\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Multiple Facts and Shared Dimensions - Honeydew Documentation\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://honeydew.mintlify.app/_mintlify/api/og/v2?division=Advanced+Modeling\u0026amp;title=Multiple+Facts+and+Shared+Dimensions\u0026amp;theme=0b845200c1ca80fd78144b6a\u0026amp;signature=f5dfeaa1f51ae99199b7a857cf7e22e1674627c61edf5db5fd093fa45f8be5b6\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/docs/mintlify-assets/_mintlify/favicons/honeydew/RTEKSf7Pgej90ivg/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Honeydew Documentation\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#abcb1a\">\u003clink data-mint-head rel=\"canonical\" href=\"https://honeydew.ai/docs/advanced-modeling/shared-dimensions\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/docs/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/advanced-modeling/shared-dimensions.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://honeydew.ai/#organization\",\"name\":\"Honeydew Documentation\",\"url\":\"https://honeydew.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/honeydew/FY_ZgBcPUZJ2-No3/logo/logo.svg?fit=max\u0026auto=format\u0026n=FY_ZgBcPUZJ2-No3\u0026q=85\u0026s=10dbf238c7bdb5bb1ee94e85eea8049f\"}},{\"@type\":\"WebSite\",\"@id\":\"https://honeydew.ai/docs#website\",\"name\":\"Honeydew Documentation\",\"url\":\"https://honeydew.ai/docs\",\"publisher\":{\"@id\":\"https://honeydew.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://honeydew.ai/docs/advanced-modeling/shared-dimensions#webpage\",\"url\":\"https://honeydew.ai/docs/advanced-modeling/shared-dimensions\",\"name\":\"Multiple Facts and Shared Dimensions\",\"dateModified\":\"2026-10-29T12:57:32.099Z\",\"isPartOf\":{\"@id\":\"https://honeydew.ai/docs#website\"},\"breadcrumb\":{\"@id\":\"https://honeydew.ai/docs/advanced-modeling/shared-dimensions#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://honeydew.ai/docs/advanced-modeling/shared-dimensions#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Modeling Reference\",\"item\":\"https://honeydew.ai/docs/architecture\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Advanced Modeling\",\"item\":\"https://honeydew.ai/docs/advanced-modeling/order-of-computation\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Multiple Facts and Shared Dimensions\",\"item\":\"https://honeydew.ai/docs/advanced-modeling/shared-dimensions\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://honeydew.ai/docs/advanced-modeling/shared-dimensions#article\",\"headline\":\"Multiple Facts and Shared Dimensions\",\"name\":\"Multiple Facts and Shared Dimensions\",\"url\":\"https://honeydew.ai/docs/advanced-modeling/shared-dimensions\",\"mainEntityOfPage\":{\"@id\":\"https://honeydew.ai/docs/advanced-modeling/shared-dimensions#webpage\"},\"dateModified\":\"2026-10-29T12:57:32.099Z\",\"publisher\":{\"@id\":\"https://honeydew.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://honeydew.ai/docs#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Honeydew Documentation\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Honeydew Documentation","nav":{"global":null,"groups":[{"group":"Quick Start","pages":[{"title":"Introduction","href":"/introduction"},{"title":"TPC-H Walkthrough","href":"/tpch-example"},{"title":"Evaluation Process","href":"/evaluation"},{"title":"Initial Setup","href":"/initial-setup"},{"title":"Support","href":"/support"}]},{"group":"Semantic Ecosystem","pages":[{"title":"Apache Ossie (OSI)","href":"/integration/apache-ossie-osi"},{"title":"From SQL to Honeydew","href":"/migration/sql-guide"},{"title":"From DAX to Honeydew","href":"/migration/dax-guide"},{"title":"From Tableau to Honeydew","href":"/migration/tableau-guide"},{"title":"Import Tools","href":"/migration/import-tools"}]},{"group":"Modeling Reference","pages":[{"title":"Architecture","href":"/architecture"},{"title":"Semantic Compiler","href":"/semantic-compiler"},{"group":"Entity Modeling","pages":[{"title":"Entities","href":"/modeling/entities"},{"title":"Source Data","href":"/modeling/source-data"},{"title":"Relations","href":"/modeling/relations"}]},{"title":"Domains","href":"/domains"},{"group":"Calculations","pages":[{"title":"Attributes","href":"/calculations/attributes"},{"title":"Metrics","href":"/calculations/metrics"},{"title":"Filters","href":"/calculations/filters"}]},{"title":"Datasets","href":"/dynamic-datasets"},{"title":"Parameters","href":"/parameters"},{"group":"Advanced Modeling","pages":[{"title":"Order of Filtering","description":null,"href":"/advanced-modeling/order-of-computation"},{"title":"Multiple Facts and Shared Dimensions","href":"/advanced-modeling/shared-dimensions"},{"title":"Conditional Filtering","description":null,"href":"/advanced-modeling/conditional-filtering"},{"title":"Multi-Grain Tables","href":"/advanced-modeling/multi-grain-tables"},{"title":"Slowly Changing Dimensions","href":"/advanced-modeling/slowly-changing-dimensions"},{"title":"Time Aware Metrics","href":"/advanced-modeling/time-metrics"},{"title":"Time Spines","href":"/advanced-modeling/time-spines"},{"title":"Handling Fan-Out and Chasm Joins","href":"/advanced-modeling/mixing-granularities"}]},{"group":"Recipes","pages":[{"title":"Overview","href":"/recipes/overview"},{"title":"How much revenue comes from a specific category?","sidebarTitle":"Metric for a specific category","href":"/recipes/category-revenue"},{"title":"What share of revenue comes from a specific category?","sidebarTitle":"Category share of total","href":"/recipes/category-revenue-share"},{"title":"Are our customers coming back?","sidebarTitle":"Active customers \u0026 stickiness","href":"/recipes/active-customers"},{"title":"Are we growing compared to last year?","sidebarTitle":"Period-over-period growth","href":"/recipes/yoy-revenue-growth"},{"title":"Are customers spending more per visit?","sidebarTitle":"Fixed level of detail metric","href":"/recipes/avg-order-value"},{"title":"What fraction of orders exceed a revenue threshold?","sidebarTitle":"Share above a threshold","href":"/recipes/high-value-order-share"},{"title":"Which truck has the most consistent daily sales?","sidebarTitle":"Average per day","href":"/recipes/avg-daily-revenue"},{"title":"Can one metric show different numbers to different teams?","sidebarTitle":"BI parameters","href":"/recipes/dynamic-bi-parameters"},{"title":"How do I give different teams their own governed view of the data?","sidebarTitle":"Domain hierarchy","href":"/recipes/domain-hierarchy"}]},{"title":"YAML Schema","href":"/yaml-schema"}]},{"group":"Context Layer","pages":[{"title":"Overview","href":"/integration/context-layer/overview"},{"title":"Deep Analysis","href":"/integration/context-layer/deep-analysis"},{"title":"Agents","href":"/integration/context-layer/agents"},{"title":"Context Management","href":"/integration/context-layer/context-management"},{"title":"AI Metadata","href":"/integration/context-layer/ai-metadata"},{"title":"Building with AI","href":"/integration/context-layer/building-with-ai"},{"title":"YAML Schema","href":"/integration/context-layer/yaml-schema"}]},{"group":"Management","pages":[{"group":"Performance","pages":[{"title":"Overview","href":"/performance/overview"},{"title":"Aggregate Aware Caching","href":"/performance/aggregate-awareness"},{"title":"Incremental Aggregate Updates","href":"/performance/aggregate-incremental-updates"},{"title":"Entity Caching","href":"/performance/entity-caching"},{"title":"Filtering and Sampling","href":"/performance/filtering-and-sampling"}]},{"group":"Governance","pages":[{"title":"Metadata","href":"/governance/metadata"},{"title":"Git Version Control","href":"/governance/git-version-control"},{"title":"Change Approval","href":"/governance/change-approval"},{"group":"CI/CD Workflow","pages":[{"title":"Overview","href":"/governance/ci-cd/overview"},{"title":"GitHub Actions","icon":"github","href":"/governance/ci-cd/github-actions"}]},{"title":"Workspaces","href":"/governance/workspaces"},{"title":"Environments","href":"/governance/environments"}]},{"group":"Monitoring","pages":[{"title":"Query history","href":"/monitoring/query-history"},{"title":"Question history","href":"/monitoring/question-history"},{"title":"Chat history","href":"/monitoring/chat-history"}]},{"title":"User Access Control","href":"/access-control/user-access-control"},{"title":"Row-Level Security","href":"/security/row-level-security"}]},{"group":"Integrations","pages":[{"title":"MCP Server","href":"/integration/mcp"},{"group":"Interfaces","pages":[{"title":"SQL Interface","href":"/integration/sql-interface"},{"title":"GraphQL API","href":"/integration/graphql-api"},{"title":"XMLA Interface","href":"/integration/xmla-interface"},{"title":"Snowflake Native App","icon":"snowflake","href":"/integration/snowflake-native-app"}]},{"group":"AI","pages":[{"title":"Slack App","icon":"slack","href":"/integration/context-layer/slack-app"},{"title":"Microsoft Teams App","icon":"microsoft","href":"/integration/context-layer/teams-app"},{"title":"Build an Embedded AI Analyst UI","sidebarTitle":"Embedded UI","href":"/integration/context-layer/embedded-ui"},{"title":"Streamlit","href":"/integration/context-layer/streamlit"},{"title":"LLM Providers","href":"/integration/context-layer/llm-providers"}]},{"group":"BI Tools","pages":[{"title":"Supported Tools","href":"/integration/bi-tools/supported-tools"},{"title":"Power BI","href":"/integration/bi-tools/powerbi"},{"title":"Excel","href":"/integration/bi-tools/excel"},{"title":"Tableau","href":"/integration/bi-tools/tableau"},{"title":"Looker","href":"/integration/bi-tools/looker"},{"title":"ThoughtSpot","href":"/integration/bi-tools/thoughtspot"},{"title":"Databricks","href":"/integration/bi-tools/databricks"},{"title":"Sigma","href":"/integration/bi-tools/sigma"},{"title":"Domo","href":"/integration/bi-tools/domo"},{"title":"Qlik","href":"/integration/bi-tools/qlik"},{"title":"Amazon Quick","href":"/integration/bi-tools/amazon-quick"},{"title":"Hex","href":"/integration/bi-tools/hex"},{"title":"Deepnote","href":"/integration/bi-tools/deepnote"},{"title":"Superset/Preset","href":"/integration/bi-tools/superset-preset"},{"title":"Metabase","href":"/integration/bi-tools/metabase"},{"title":"Mode Analytics","href":"/integration/bi-tools/mode"},{"title":"Lightdash","href":"/integration/bi-tools/lightdash"},{"title":"Holistics","href":"/integration/bi-tools/holistics"},{"title":"Redash","href":"/integration/bi-tools/redash"}]},{"group":"Catalogs","pages":[{"title":"Data Catalogs","href":"/integration/catalogs/supported-tools"},{"title":"Atlan","href":"/integration/catalogs/atlan"},{"title":"Collibra","href":"/integration/catalogs/collibra"},{"title":"DataHub","href":"/integration/catalogs/datahub"}]},{"group":"Observability","pages":[{"title":"OpenTelemetry","href":"/integration/observability/opentelemetry"}]},{"group":"SQL Clients","pages":[{"title":"Retool","href":"/integration/bi-tools/retool"},{"title":"Database Tools \u0026 IDEs","href":"/integration/bi-tools/sql-tools-ides"},{"title":"Jupyter","href":"/integration/bi-tools/jupyter"},{"title":"Python","href":"/integration/bi-tools/python"},{"title":"JavaScript","href":"/integration/bi-tools/javascript"}]},{"group":"Data Sources","pages":[{"title":"Snowflake","icon":"snowflake","href":"/integration/data-sources/snowflake"},{"title":"Databricks","href":"/integration/data-sources/databricks"},{"title":"Google BigQuery","icon":"google","href":"/integration/data-sources/bigquery"}]},{"group":"Git","pages":[{"title":"GitHub","icon":"github","href":"/integration/git/github"},{"title":"GitLab","icon":"gitlab","href":"/integration/git/gitlab"},{"title":"Bitbucket","icon":"bitbucket","href":"/integration/git/bitbucket"},{"title":"Azure DevOps","icon":"microsoft","href":"/integration/git/azure-devops"}]},{"group":"ELT Tools","pages":[{"title":"Data Pipeline Architecture","href":"/integration/etl-tools/pipeline-architecture"},{"title":"dbt","href":"/integration/etl-tools/dbt"}]}]},{"group":"Security","pages":[{"title":"Security \u0026 Compliance","href":"/security/security"},{"title":"API Keys","href":"/access-control/api-keys"},{"group":"Authentication","pages":[{"title":"Single Sign-On (SSO)","href":"/access-control/sso"},{"title":"Okta SSO Integration (OIDC)","href":"/access-control/okta"},{"title":"Microsoft Entra ID (formerly Azure Active Directory)","href":"/access-control/entra-id"},{"title":"PingIdentity SSO Integration (SAML)","href":"/access-control/ping-identity"},{"title":"OIDC Provider SSO Integration","href":"/access-control/oidc-provider"},{"title":"SAML Provider SSO Integration","href":"/access-control/saml-provider"},{"title":"Windows Authentication (Kerberos)","href":"/access-control/windows-authentication"}]},{"title":"IP Access Control","href":"/access-control/ip-access-control"},{"title":"Vulnerability Disclosure Policy","href":"/security/vulnerability-disclosure-policy"}]},{"group":"Release Notes","pages":[{"title":"Release Notes","href":"/release-notes"}]}]},"basePath":"","title":"Multiple Facts and Shared Dimensions - Honeydew Documentation","buildId":"dpl_9yaRmq8qi7yyMZn9oEWmKEdYMvGZ","deploymentId":"dpl_9yaRmq8qi7yyMZn9oEWmKEdYMvGZ","dynamics":[],"chunks":[]}