Demand signal
Finding unmet product needs across regions while excluding an internal namespace.
A retailer wants to hear customers describing needs its current range does not meet — in the consumer segment it actually sells to, and without its own staff chatter contaminating the signal.
MATCH DIRECTION(["unmet need", "product frustration"]) CONE 0.4
AND CONTRAST(
ATTRACT ["home kitchen", "small appliance"],
REPEL ["professional equipment", "commercial grade"]
)
NAMESPACE "org:retailco-eu", "org:retailco-us", NOT "org:retailco-internal"
WINDOW 30d
{
"match": {
"and": [
{ "direction": { "toward": ["unmet need", "product frustration"], "cone": 0.4 } },
{ "contrast": {
"attract": ["home kitchen", "small appliance"],
"repel": ["professional equipment", "commercial grade"] } }
]
},
"namespace": {
"include": ["org:retailco-eu", "org:retailco-us"],
"exclude": ["org:retailco-internal"]
},
"window": "P30D"
}
Why each clause is there
DIRECTION names a stance, not a product. "Unmet need" and "product
frustration" describe how someone is talking, and the interesting messages are
the ones nobody thought to categorise. A cone finds that posture across product
categories that do not exist in the catalogue yet — which is the entire point of
a demand signal.
CONTRAST sets the segment. Home kitchen and commercial kitchen content
share their whole vocabulary. Repelling from "professional equipment" and
"commercial grade" separates them where no keyword rule could.
The namespace exclusion matters more than it looks. Internal staff discuss
product gaps constantly, in exactly this register. Left in, the query would
mostly rediscover the company's own opinions and read as strong external demand.
NOT "org:retailco-internal" is what keeps the signal a signal.
WINDOW 30d. Demand signals are cumulative — a single message is noise, a
month of them is a trend. Note the JSON form normalizes durations to ISO 8601,
so this comes back as "P30D".
Reading the results
This query is deliberately unfiltered: no WITHIN anywhere, so nothing is
hard-rejected and both clauses contribute to ranking. That suits a signal you
intend to read in bulk and skim, rather than an alert you want to fire rarely.
If you turn it into an alert, add WITHIN to the CONTRAST first — the segment
boundary is where a false positive costs the most.