SIMILARITY_MATCH Architecture & MRO Applications
CIRPASS-2 DPP Validator • Enterprise Sourcing Intelligence
← Back to DPP Dashboard
🔬 Deep Dive WhitepaperCIRPASS-2 Core Innovation

Deconstructing the SIMILARITY_MATCH Algorithm

How the European Digital Product Passport automatically identifies unknown JSON trees using Weighted Jaccard & PostgreSQL GIN arrays — and how this exact engine transforms industrial MRO materials sourcing, RFQ quotation, and cross-reference cataloging.

Explore Core Algorithm Industrial MRO Applications Interactive Simulator
📌 Executive Summary: The Zero-Schema Dilemma
Why rigid schemas fail in decentralized networks and how autonomous similarity matching solves enterprise interoperability.
⚠️ The Fragmentation Crisis

In global supply chains, thousands of manufacturers format data differently. Forcing every supplier or customer to declare explicit schema IDs (e.g. v1.0.4-patch2) results in 85% validation rejections due to minor naming mismatches.

🧠 Autonomous Detection

The SIMILARITY_MATCH engine in dpp-validator ingests blind JSON payloads, flattens them into abstract structural trees, and queries PostgreSQL GIN indexes to detect the intended industry template in under 4 milliseconds.

🏭 B2B MRO Superpower

The exact same math powers industrial MRO distributors: mapping chaotic supplier spec sheets (SKF, NSK, Timken) against vague customer RFQ requests, auto-building master item catalogs, and generating instant cross-brand quotations.

⚙️ Part 1: The Core Algorithm Under the Hood
Deep dive into the source code of dpp-validator (Java Quarkus + PostgreSQL Reactive Client).
1

Phase 1: Recursive AST Path Flattening (JsonPropertyExtractor.java)

When an arbitrary JSON document hits /validate/v1, it contains nested objects and arrays. The extractor performs a recursive depth-first walk, transforming the tree into a flat set of dot-notation paths while normalizing array elements with []:

// Input JSON:
{ "Manufacturer_BrandOwner": { "ContactDetails": { "emailAddress": "compliance@shoe.eu" } } }

// Extracted Paths Set (inputProps):
paths = [
  "Manufacturer_BrandOwner",
  "Manufacturer_BrandOwner.ContactDetails",
  "Manufacturer_BrandOwner.ContactDetails.emailAddress"
]
2

Phase 2: Database Ingestion & GIN Array Intersection (PgSQLJsonSchemaRepository.java)

Every registered Schema in json_schemas stores its required_paths TEXT[] indexed with PostgreSQL GIN (Generalized Inverted Index). The repository executes an ultra-fast CTE query:

-- Executed by dpp-validator via Vert.x Reactive SQL Client
WITH schema_scores AS (
    SELECT
        sm.id, sm.schema_name, sm.schema_version, sm.required_paths_count,
        (
            -- Count how many of this Schema's required paths are present in the Input
            SELECT COUNT(*)::int
            FROM unnest(sm.required_paths) AS rp
            WHERE rp = ANY($1)  -- $1 = array of input properties
        ) AS matched_count,
        $2::int AS input_count
    FROM json_schemas sm
),
base_jaccard AS (
    SELECT
        id, schema_name, schema_version, matched_count, required_paths_count,
        CASE
            WHEN required_paths_count = 0 THEN 0.0
            -- Penalize extra unrecognized fields with a 0.6 dampener
            ELSE matched_count::float / (required_paths_count + 0.6 * (input_count - matched_count))::float
        END AS jaccard_score
    FROM schema_scores
)
Weighted Jaccard = matched_count / (required_paths_count + 0.25 * (input_count - matched_count))
3

Phase 3: Pattern Properties Refinement (Regex Matching)

Many industrial schemas declare dynamic attributes using regular expressions (e.g. ^mro_spec_[0-9]+$). The Java layer inspects schema_pattern_properties and rewards candidates that match wildcards:

// Pattern Property refinement in Java
int matchedPatterns = countMatchedPatterns(patterns, parsedInput);
int totalMatched = matchedBasePaths + matchedPatterns;
int totalRequired = requiredBasePaths + patterns.size();
candidate.finalScore = Math.max((double) totalMatched / inputCount, 
                                totalMatched / (totalRequired + 0.25 * (inputCount - totalMatched)));
4

Phase 4: Candidate Gating & Deep Schema Validation (PlainJsonValidator.java)

The engine enforces an uncompromising gate: candidates must achieve finalScore >= 0.3 (30% structural overlap). If no candidate reaches this threshold, it returns MatchType.NONE:

// Threshold decision in PlainJsonValidator.java
return candidates
    .filter(c -> c.finalScore >= 0.3)
    .max(Comparator.comparingDouble(a -> a.finalScore))
    .map(this::asMatchResult)
    .orElse(MatchResult.emptyResult());

// If MatchType.NONE:
// -> "No JSON matchResult found matching by similarity the input JSON"
🏭 Part 2: Transforming Industrial MRO Sourcing & Reselling
How B2B industrial distributors, trading companies, and procurement hubs can reuse this exact architecture to automate RFQs, eliminate duplicate SKUs, and cross-reference multi-vendor catalogs.
⚠️ The MRO Chaos in Traditional Trading

Industrial suppliers (SKF, NSK, Timken, SMC, Festo) code identical components differently. A customer RFQ asks for "Ball bearing 20x47x14 rubber seal high temp". Sales engineers waste 45 minutes manually opening vendor PDF catalogs to find whether SKF 6204-2RSH/C3HT matches NSK 6204 DDU C3E.

🚀 The Algorithmic Solution

By adapting the SIMILARITY_MATCH pipeline, the MRO Sourcing Hub flattens technical specs into canonical engineering vectors. It cross-compares customer requirements against hundreds of supplier databases simultaneously, generating an instant match score and cross-reference quote!

Architecture Layer DPP Context (EU Regulation) Industrial MRO Sourcing Context
1. Ingestion Target JSON / JSON-LD Product Passport from brand carriers Customer RFQ (Excel, PDF, Email, API) & Supplier Spec Sheets
2. Normalization Engine JsonPropertyExtractor extracts hierarchical JSON keys MRO Thesaurus extracts canonical attributes (Bore, OD, Width, Material, RPM, Seal)
3. Schema / Master Catalog json_schemas table in PostgreSQL (Footwear, Batteries, Textiles) mro_master_items Golden Records table with GIN array indexes
4. Matching Formula Weighted Jaccard over required_paths Hybrid: Structural Jaccard (80%) + Numeric Tolerance Scoring (20%)
5. Actionable Output VALID / INVALID compliance report for EU Registry Top 3 Cross-Brand Replacement options with Price, Stock & Tolerance Delta

🔍 Real-World Case Study: Cross-Brand Bearing Matching

Customer RFQ Input:
{
  "item_type": "deep_groove_ball_bearing",
  "dimensions": {
    "inner_diameter_mm": 20.0,
    "outer_diameter_mm": 47.0,
    "width_mm": 14.0
  },
  "sealing": "contact_rubber_seal_both_sides",
  "clearance": "C3",
  "application": "high_speed_electric_motor"
}
Algorithmic Match Result (PostgreSQL GIN):
{
  "matched": true,
  "top_matches": [
    {
      "brand": "SKF",
      "part_number": "6204-2RSH/C3",
      "similarity_score": 0.985,
      "exact_dimensions": true,
      "price_usd": 4.85,
      "lead_time": "In Stock (2,400 pcs)"
    },
    {
      "brand": "NSK",
      "part_number": "6204-DDUC3",
      "similarity_score": 0.978,
      "exact_dimensions": true,
      "price_usd": 4.10,
      "lead_time": "In Stock (1,200 pcs)"
    }
  ]
}
🧪 Part 3: Interactive Similarity Simulator Sandbox
Test the matching logic directly in your browser. Edit the Schema and the Input Payload, adjust the threshold, and watch the real-time Jaccard Score computation!
0.30
Registered Schema / Catalog Template (JSON)
Incoming Blind Payload / Customer RFQ (JSON)
MATCH TYPE: SIMILARITY_MATCH Matched 10 of 10 required paths
Score: 0.892
Precision: 1.000 • Weighted Jaccard: 0.892 • Status: Qualified for deep validation
🗺️ Part 4: Enterprise Implementation Blueprint
How to deploy this similarity engine inside your ERP, WMS, or Trading Sourcing Portal.
1️⃣ Data Extraction Pipeline

Deploy an OCR / NLP parser to convert raw supplier catalogs (PDF, CSV, API) and RFQs into normalized key-value trees. Map synonyms using a shared industrial thesaurus (e.g. DIN 625 = ISO 15 = Radial Ball Bearing).

2️⃣ PostgreSQL GIN Store

Index millions of parts in PostgreSQL using TEXT[] arrays and GIN indexes. The ANY() and unnest() SQL operators evaluate 100,000 components in under 8ms on standard hardware.

3️⃣ Automated Quotation Bot

Hook the similarity score into your CRM / ERP (SAP, Odoo). When an RFQ arrives, the engine auto-drafts the quote with the best-matched item, highlighting margins, stock availability, and equivalent brand alternatives.