Guide
How to match products across retailers without barcodes
Price comparison, competitor monitoring and marketplace catalogues all need the same thing: knowing that four listings at four retailers are one product. Barcodes would settle it, but most retailer pages don't show one, and own-label goods have a different barcode at every shop. So the match has to come from the listing itself.
Why name matching gets it wrong
The usual first attempt is to compare titles: normalise the text, score the similarity, merge anything above a threshold. It fails in both directions. Titles for the same product vary more than you would expect between retailers, and titles for different products can differ by a single character.
Hovis Soft White Medium Sliced Bread 400g
Hovis Soft White Medium Sliced Bread 800g
98% similar as strings. Two different products.
Size is the obvious case, but every category has its own:
- Sony WH-1000XM4Sony WH-1000XM5a different generation
- CeraVe Moisturising CreamCeraVe Moisturising Lotiona different form
- Makita DHP485ZMakita DHP485RFJbare tool against a kit
- Pedigree Adult 12kgPedigree Puppy 12kga different life stage
Raise the threshold and the true matches with messy titles fall apart. Lower it and these pairs merge. Hand-written rules per category patch the worst cases, then need maintaining forever.
Decide what the product is, then match
The fix is to stop comparing titles and compare products. Read each listing the way a shopper would: title, size, ingredients, storage advice and photo together. Write down what it physically is: brand, range, variant, size, and whatever else decides a match in that category. Two listings match when those facts agree.
A language model can do that reading for any category without rules, but the order of work matters more than the model:
1. Settle brand and size first
A wrong brand or size explains most wrong matches, so check them before any matching runs. Every listing in scope needs a brand and a usable size. If a size is ambiguous, look at what near-identical listings at other retailers agree on.
2. Label each listing
Give each listing a specific product type (sliced white bread, not bakery), so matching only compares like with like.
3. Match within each label
Group listings that describe the same product and keep near misses apart. Record a confidence and the reason for every match, so it can be checked later.
4. Check every result, not a sample
Some mistakes only show once the matches exist. Look for them mechanically and send what can't be settled to a person.
Checks that catch bad matches
Most of these need no model at all:
- One listing per retailer. A retailer sells a product once. Two Waitrose listings on one product, a 4 pack and a minimum-5 pack of apples, mean one of them is a different product.
- Size stretch. A listing far from its product's median size is suspect, especially when the same retailer had a closer-sized listing that should have matched instead.
- Low confidence. Queue every match below a set confidence for review rather than trusting it.
- Duplicate labels. The same item filed under two labels never gets matched with itself. Near-identical label names and titles find these.
- Values that flip back. A fact that returns to a value it already left means two passes disagree. Decide it once and lock it.
When a check can't settle something from the listing, fetch the live product page and photo and judge again with the full description as evidence. When a reviewer finds a new kind of mistake, add the check that would have caught it, so it is caught everywhere from then on.
See it on real listings
catalogued.ai runs this pipeline on listings from UK supermarkets and plumbing merchants. The demo shows each product with the listings matched to it and the checks it passed.