#862 Work being done on "Querying Relationships"?

Mike Melillo Wed 21 Oct 2020

Referring specifically to: https://project-haystack.dev/doc/docHaystack/Relationships

Trying to navigate currently open working groups, it doesn't seem like there's anything specifically targeted at addressing evolving this topic, maybe I've missed it. I'm not sure what precisely would go into that conversation, but since the introduction of Haystack 4 to SkySpark I've spent a decent amount of time working on leveraging them to infer relationships between entities. This has specifically been an effort to develop more contextual relationships between entities in a database without explicitly defining bundles and bundles of "xRef" tags.

For example, if I am reviewing some information about a {point, air-temp, equipRef: @equip} record, I already know that in searching for any "related" entities, they probably have to do with ^quantity of temp, and ^substance/phenomenon of air. Furthermore, I could look at @equip's ^equipFunction, its input/output phenomenon to draw more abstract relationships. In this example, maybe @equip conditions air-temp via output air, but because @equip is input chilled-water, I now have context for other records to look for.

I think there is a fairly logical thought process for building a comprehensive set of querying tools/rules/guidelines to leverage these relationships, but I'm not sure how to best express/formalize them -- as they cannot be really efficient until that "Querying Relationships" syntax is vetted out. Right now having to grab entire sets of def libraries in a SkySpark instance to do this kind of querying is very time consuming.

Sidebar, new to the project-haystack community (at least as more than combing posts, reading documentation) apologies if anything here is misguided for how the community generally tackles things, and where the line is drawn between a vendor specific thread (e.g. SkyFoundry or chosen brand of tool) vs a haystack community topic. My experience is best summarized as SkySpark & Tridium FDD/BMS Integrator.


Brian Frank Wed 21 Oct 2020


The short answer is: its not designed yet.

We just recently this summer finalized the naming convention for flow relationships (airRef, elecRef, etc).

The next step will be to enhance the filter language. There are several outstanding issues:

  1. How to query without regard to details (for example fan point directly in ahu, or nested in a fan equip, or nested in a fan sub-equip in turn nested in duct sub-equip)
  2. How to query energy/substance flows through multiple levels (find ahu which supplies a zone by traversing thru the airRef tags)
  3. How to leverage inference in the queries to take advantage of all the extra meta data in the defs

If it looks like a design emerges which elegantly solves these problems it might just be a forum post proposal. Otherwise it might requiring conventing a new WG to brainstorm or work out a design.

Mike Melillo Thu 22 Oct 2020

Hmm, I have a hard time feeling I'd be anything other than in over my head here, but I'll throw up the decisions I've made for my scripts anyway and maybe they'll spark some conversation.

First to take a wild crack at the 3 open items you mentioned.

(1) Tiered querying

If we have the following dicts

  • {discharge, air, temp, point, equipRef: @dischargeDuct}
  • {discharge, air, fan, equip, equipRef: @ahu}
  • {discharge, air, duct, equip, equipRef: @ahu}
  • {discharge, air, fan, cmd, point, equipRef: @dischargeFan}

I would like to have my discharge temp point, query something like "find related xRef records". The xRef element of that query could be for a specific ref like equipRef or for some default to look at any present Ref tag. The fun starts with qualifying what to do with different types of ref tags.

Step by step, we would create a collection of valid equipRef ids that would return for this query. That starting step would basically build a tree of equip ids by looping through each resulting new equip until there are no new equips added, terminating the collection process. Then collect all the child points equipRefd to that collection. At that point we would have collected the family of equips and points that represent some top level equip (like an ahu).

To achieve this functionality, I think there should be an addition to the def model where certain defs like equip would need something added to them, say like a nestable marker tag. That tag would indicate that the xRef form of this def, i.e. equipRef, would invoke the above described tiered query. If a def does not include nestable, like air, it would consequently not cause the tiered querying to occur when looking for related records (so in the example above, it would just find records directly pointed at the same airRef).

This also requires a stricter use around how different xRef tags are used to prevent unintentional nesting references. Not sure how much I should address that implementation best practice here.

(2) Querying flows through multiple levels

I think it makes sense for this functionality to include support to query along one or multiple taxonomies or libs. For instance, when I want to find related records to a point dict, I need to define what I mean by related. Vocabulary choice might be arbitrary here, but conceptually I think of the way two entities relating in terms of a dimension. For instance, if I call two dicts related because they both contain the point marker tag, I would say they relate along their entity dimension. A similar comparison could be said for two dicts containing the air tag relate along the phenomenon or substance dimension, and so on for things like quantity or equips relating by process etc.

I don't feel satisfied with my current implementation of the above idea, but here's basically how it works.

I have static decisions made for a few particular defs, say something like point. When I begin querying against a dict containing that marker, there are rules for what other kind of defs I am searching for to build a relational tree. With a point, phenomenon and quantity are my two key targets (currently). The next decision is what to do with those identifiers, which I will try to lay this out with a simple example

  • {id: @1, zone, air, temp, sensor, equipRef: @2}
  • {id: @2, vav, equip, airRef: @3, airCooling, cools: air}
  • {id: @3, ahu, equip, chilledWaterCooling, cools: air, chilledWaterRef: @4}
  • {id: @4, chiller, equip, coolingProcessType: condenserWater, cools: chilledWater, condenserWaterRef: @..}
  • {id: @5, chilled, water, leaving, temp, sensor, equipRef: @4}

The short goal of my query is to say given dict @1, to say find relations and one of those results should be @5.

The reason I expect that, is because it is a zone air temp sensor. Air is cooled by its equipRef'd vav @2. I also know that @2's input or consumption is also air, so I should be able to find something that @2 is ref'd to which outputs air and has some kind of a cooling process. That leads me to my air handler, and now I can make a phenomenon switch from air to water and my substance of interest, because the ahu outputs air but again it inputs chilled water. I can now make the same logical hop to the chiller, consequently its chilled water leaving temp. That would be my controls guy reasoning from point A to point Z.

Obviously, I'm skipping any other air temp sensors on the vav or ahu, and other water temp sensors on the chilled water plant.

Now we get onto my assumptions to make this work on a programming level, and current limitations and problems that I can see with this approach.

  1. I'm assuming relationships should be drawn based upon commonality between different dimensions of the def structure
  2. I have to make an assumption on how many dimensions make something a valid relationship/correllated point
    1. is just a phenomenon match good enough? or do I need phenomenon + quantity?
    2. I think just one match is good enough because otherwise I would miss out on air + pressure coming off the AHU, which could certainly be related to my zone air temp
  3. I have to statically define which libs or taxonomies and a few subtypes/supertypes that basically become my main dimensions to look for matches across, or to traverse those subtypes to find additional dimensions to search
    1. This is basically a recursive process where essentially I start with a point, find out what equipment controls it and how (choice -> equipFunction and process on its equipRef)
    2. Then proceed to use those equipFunction and process defs to determine other phenomena to look for elsewhere
  4. Basically it's not super flexible in my current attempt at this... I've narrowed it to determine a certain kind of relationship, which is just following a process/phenomenon tree. One of my next targets is to determine some language for being able to state what kind of relationship tree I'm looking to follow as a part of my input.
  5. Because I'm relying on recursion, this can be a time consuming when executing (compared to normal queries)

(3) I think that's about as far down that rabbit hole as I can attempt to articulate on a first pass. I feel like what I'm describing is a decent crude attempt at leveraging one kind of inference, but there are a great deal more, and require a less specific approach.

Login or Signup to reply.