AdamG
AdamG

Reputation: 68

Is there a way to do a "left outer join" like query in PromQL?

I am trying to use two metrics (that share some labels, including one that I can use as an UUID) that should describe the same entities, in order to create alerts/dashboard that will alert me one an entity reports in one metric but not the other.

For example, for the following metrics:

item_purchases{name="item1", count="5"}
item_purchases{name="item2", count="7"}

item_stock{name="item1", in_stock="1"}
item_stock{name="item2", in_stock="0"}
item_stock{name="item3", in_stock="1"}

I use item_stock as my "source of truth", and I'm trying to write a query that will return:

item_stock{name="item3", ...} # I don't care about the other labels, just the name.

I already have a query that helps me filter on certain conditions (For example - if an item was purchased but is not in stock like "item2") that looks something like:

item_purchases{in_stock="1"} * on (name) group_left () (item_purchases)

but unfortunately it just drops all the records in item_stock that don't have a matching timeseries in item_purchases - like "item3", which is actually the result I'm looking for.

Does anyone have any experience coding these type of queries? Are they even possible in PromQL or should I revert to some other solution?

Upvotes: 5

Views: 7934

Answers (1)

anemyte
anemyte

Reputation: 20296

It is possible using unless operator:

item_stock unless item_purchases

Results in a vector consisting of the elements of item_stock for which there are no elements in item_purchases with exactly matching label sets. All matching elements in both vectors are dropped.

Note that the metrics in question do not have 'exactly matching label sets' (name is common but count and in_stock are not). In this case you can use on to set the list of labels to match:

item_stock unless on(name) item_purchases

Upvotes: 5

Related Questions