### Compile and Install Locally Source: https://github.com/intuit/fuzzy-matcher/blob/master/CONTRIBUTING.md Build, test, and install the fuzzy-matcher project locally after cloning. Uses Apache Maven. ```bash mvn clean install ``` -------------------------------- ### Install Maven on Ubuntu Source: https://github.com/intuit/fuzzy-matcher/blob/master/CONTRIBUTING.md Install Apache Maven using the apt-get package manager on Ubuntu. Maven 4.0 or above is required. ```bash sudo apt-get install maven ``` -------------------------------- ### Install Maven on OSX Source: https://github.com/intuit/fuzzy-matcher/blob/master/CONTRIBUTING.md Install Apache Maven using Homebrew on macOS. Maven 4.0 or above is required. ```bash brew install maven ``` -------------------------------- ### Install Maven on Windows Source: https://github.com/intuit/fuzzy-matcher/blob/master/CONTRIBUTING.md Install Apache Maven using Chocolatey on Windows. Maven 4.0 or above is required. Run from an elevated prompt. ```bash choco install maven ``` -------------------------------- ### Process and Print Match Results Source: https://github.com/intuit/fuzzy-matcher/blob/master/README.md Iterate through the results map to access and display the matched documents, their matched counterparts, and the similarity score. This example prints the details to the console. ```java result.entrySet().forEach(entry -> { entry.getValue().forEach(match -> { System.out.println("Data: " + match.getData() + " Matched With: " + match.getMatchedWith() + " Score: " + match.getScore().getResult()); }); }); ``` -------------------------------- ### Custom Pre-processing Function Override for String Elements Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Replaces default dictionary-based normalization with a custom Java function for domain-specific preprocessing. This example strips royal titles and generational suffixes from names. ```java import com.intuit.fuzzymatcher.component.MatchService; import com.intuit.fuzzymatcher.domain.*; import static com.intuit.fuzzymatcher.domain.ElementType.*; // Custom dictionary to strip royal titles and generational suffixes Map titleDict = new HashMap<>(); titleDict.put("Queen", ""); titleDict.put("Third", ""); titleDict.put("III", ""); titleDict.put("Prince", ""); Function stripTitles = str -> Arrays.stream(str.split("\\s+")) .map(word -> titleDict.getOrDefault(word, word)) .filter(w -> !w.isEmpty()) .collect(Collectors.joining(" ")); List royals = Arrays.asList( new Document.Builder("1") .addElement(new Element.Builder().setType(NAME) .setValue("Victoria Third") .setPreProcessingFunction(stripTitles) .createElement()) .createDocument(), new Document.Builder("2") .addElement(new Element.Builder().setType(NAME) .setValue("Queen Victoria III") .setPreProcessingFunction(stripTitles) .createElement()) .createDocument() ); MatchService matchService = new MatchService(); Map>> result = matchService.applyMatch(royals); // Both normalize to "Victoria" and match with score 1.0 System.out.println("Matches found: " + result.size()); // → 2 ``` -------------------------------- ### Build a Document for Matching Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Construct a Document object, which is the primary unit for matching. Each document requires a unique key and can contain multiple Elements, with an optional overall threshold for matches. ```java import com.intuit.fuzzymatcher.domain.Document; import com.intuit.fuzzymatcher.domain.Element; import static com.intuit.fuzzymatcher.domain.ElementType.*; // Build a document representing a contact record Document contact = new Document.Builder("contact-001") .addElement(new Element.Builder().setType(NAME).setValue("Steven Wilson").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("45th Avenue 5th st.").createElement()) .addElement(new Element.Builder().setType(EMAIL).setValue("steven.wilson@gmail.com").createElement()) .addElement(new Element.Builder().setType(PHONE).setValue("(512) 234-5678").createElement()) .setThreshold(0.5) // document is a match if overall score >= 0.5 .createDocument(); ``` -------------------------------- ### Check Java Version Source: https://github.com/intuit/fuzzy-matcher/blob/master/CONTRIBUTING.md Verify your Java Development Kit version. Requires Java JDK 11 or higher. ```bash java -version ``` -------------------------------- ### Match Service: Apply Match by Document with Existing List Source: https://github.com/intuit/fuzzy-matcher/blob/master/README.md Employ this method when creating a new document to ensure no similar document already exists in your system. ```java matchService.applyMatchByDocId(Document document, List matchWith) ``` -------------------------------- ### Numeric and Date Matching with NEAREST_NEIGHBORS Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Illustrates default and strict numeric matching using NEAREST_NEIGHBORS. Also shows date matching where values within a calculated range are considered matches. ```java import com.intuit.fuzzymatcher.component.MatchService; import com.intuit.fuzzymatcher.domain.*; import static com.intuit.fuzzymatcher.domain.ElementType.*; // Match transaction amounts — values within 10% of each other match (default neighborhoodRange=0.9) List amounts = Arrays.asList(100.54, 200.00, 100.00, 99.50); AtomicInteger id = new AtomicInteger(1); List txDocs = amounts.stream().map(amt -> new Document.Builder(String.valueOf(id.getAndIncrement())) .addElement(new Element.Builder().setType(NUMBER).setValue(amt).createElement()) .createDocument() ).collect(Collectors.toList()); MatchService matchService = new MatchService(); Map>> result = matchService.applyMatch(txDocs); // 100.54, 100.00, and 99.50 all match each other (within 10%) // 200.00 has no match // Strict matching: neighborhoodRange=0.99 means values must be within 1% List strictDocs = amounts.stream().map(amt -> { AtomicInteger sid = new AtomicInteger(1); return new Document.Builder(String.valueOf(id.getAndIncrement())) .addElement(new Element.Builder().setType(NUMBER).setValue(amt) .setNeighborhoodRange(0.99).createElement()) .createDocument(); }).collect(Collectors.toList()); // Date matching — dates within ~36 days of each other match at neighborhoodRange=0.9 List dates = Arrays.asList( new SimpleDateFormat("MM/dd/yyyy").parse("01/01/2024"), new SimpleDateFormat("MM/dd/yyyy").parse("01/15/2024"), new SimpleDateFormat("MM/dd/yyyy").parse("06/01/2024") ); List dateDocs = dates.stream().map(d -> new Document.Builder(String.valueOf(id.getAndIncrement())) .addElement(new Element.Builder<>().setType(DATE).setValue(d).createElement()) .createDocument() ).collect(Collectors.toList()); Map>> dateResult = matchService.applyMatch(dateDocs); // Jan 1 and Jan 15 match; Jun 1 does not match either ``` -------------------------------- ### Prepare Input Data as Documents Source: https://github.com/intuit/fuzzy-matcher/blob/master/README.md Convert raw string array data into a List of Document objects. Each Document can contain multiple Elements, such as NAME and ADDRESS, with specified types. ```java String[][] input = { {"1", "Steven Wilson", "45th Avenue 5th st."}, {"2", "John Doe", "546 freeman ave"}, {"3", "Stephen Wilkson", "45th Ave 5th Street"} }; List documentList = Arrays.asList(input).stream().map(contact -> { return new Document.Builder(contact[0]) .addElement(new Element.Builder().setValue(contact[1]).setType(NAME).createElement()) .addElement(new Element.Builder().setValue(contact[2]).setType(ADDRESS).createElement()) .createDocument(); }).collect(Collectors.toList()); ``` -------------------------------- ### Configure an Element with Customizations Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Configure individual Elements within a Document. This allows for setting specific weights, thresholds, neighborhood ranges, and overriding default pre-processing or matching functions. ```java import com.intuit.fuzzymatcher.domain.Element; import com.intuit.fuzzymatcher.domain.MatchType; import static com.intuit.fuzzymatcher.domain.ElementType.*; import static com.intuit.fuzzymatcher.function.PreProcessFunction.*; import static com.intuit.fuzzymatcher.function.TokenizerFunction.*; // A weighted phone element — double-weight boosts document score when phone matches Element phoneElement = new Element.Builder() .setType(PHONE) .setValue("(512) 234-5678") .setWeight(2.0) // doubles its contribution to document score .setThreshold(0.5) // element must score >= 0.5 to count .createElement(); // A NAME element with a custom pre-processing function Element nameElement = new Element.Builder() .setType(NAME) .setValue("Dr. John Smith Jr.") .setPreProcessingFunction(removeSpecialChars()) // override default namePreprocessing() .createElement(); // A NUMBER element with a tighter neighborhood range Element amountElement = new Element.Builder() .setType(NUMBER) .setValue(100.54) .setNeighborhoodRange(0.99) // values must be within 1% of each other .createElement(); // A DATE element Element dateElement = new Element.Builder() .setType(DATE) .setValue(new java.text.SimpleDateFormat("MM/dd/yyyy").parse("01/15/2024")) .setNeighborhoodRange(0.9) .createElement(); ``` -------------------------------- ### Match Service: Apply Match by Document ID with Existing List Source: https://github.com/intuit/fuzzy-matcher/blob/master/README.md This method is suitable for matching a new set of documents against a pre-existing list in your system, often used during bulk imports. ```java matchService.applyMatchByDocId(List documents, List matchWith) ``` -------------------------------- ### Apply Fuzzy Matching Source: https://github.com/intuit/fuzzy-matcher/blob/master/README.md Instantiate the MatchService and use its applyMatchByDocId method to find matches within a list of documents. The result is a map where keys are document IDs and values are lists of potential matches. ```java MatchService matchService = new MatchService(); Map>> result = matchService.applyMatchByDocId(documentList); ``` -------------------------------- ### Built-in Tokenizer Functions for Text Elements Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Demonstrates how to use different built-in tokenizer functions to process string elements. Override the default tokenizer via Element.Builder.setTokenizerFunction(). ```java import com.intuit.fuzzymatcher.function.TokenizerFunction; import com.intuit.fuzzymatcher.domain.Element; import static com.intuit.fuzzymatcher.domain.ElementType.*; // wordTokenizer — splits on whitespace; default for TEXT Element wordEl = new Element.Builder().setType(TEXT) .setValue("quick brown fox") .setTokenizerFunction(TokenizerFunction.wordTokenizer()) // tokens: ["quick", "brown", "fox"] .createElement(); // wordSoundexEncodeTokenizer — splits on whitespace then Soundex-encodes each word // "Steven" → S315, "Wilson" → W425 (same as "Stephen" → S315, "Wilkson" → W425) Element soundexEl = new Element.Builder().setType(NAME) .setValue("Steven Wilson") .setTokenizerFunction(TokenizerFunction.wordSoundexEncodeTokenizer()) .createElement(); // triGramTokenizer — 3-character sliding window; default for EMAIL Element triEl = new Element.Builder().setType(EMAIL) .setValue("parker.james") .setTokenizerFunction(TokenizerFunction.triGramTokenizer()) // tokens: ["par","ark","rke","ker","er.","r.j",".ja","jam","ame","mes"] .createElement(); // chainTokenizers — combine multiple tokenizers (added in v1.1.0) Element chainedEl = new Element.Builder().setType(NAME) .setValue("J.R. Smith") .setTokenizerFunction( TokenizerFunction.chainTokenizers( TokenizerFunction.wordTokenizer(), TokenizerFunction.wordSoundexEncodeTokenizer() ) ) .createElement(); ``` -------------------------------- ### MatchService.applyMatchByDocId(List, List) Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Checks a batch of incoming documents against an existing repository for duplicates. Only source documents appear as keys in the result map; the `matchWith` list acts as the reference corpus. ```APIDOC ## `MatchService.applyMatchByDocId(List, List)` — Match new records against an existing list Checks a batch of incoming documents against an existing repository for duplicates. Only source documents appear as keys in the result map; the `matchWith` list acts as the reference corpus. ```java import com.intuit.fuzzymatcher.component.MatchService; import com.intuit.fuzzymatcher.domain.*; import static com.intuit.fuzzymatcher.domain.ElementType.*; // Existing system records List existing = Arrays.asList( new Document.Builder("existing-1") .addElement(new Element.Builder().setType(NAME).setValue("James Parker").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("123 new st. Minneapolis MN").createElement()) .addElement(new Element.Builder().setType(PHONE).setValue("(123) 234 2345").setWeight(2).setThreshold(0.5).createElement()) .addElement(new Element.Builder().setType(EMAIL).setValue("jparker@gmail.com").setThreshold(0.5).createElement()) .createDocument() ); // New records from a bulk import List incoming = Arrays.asList( new Document.Builder("import-1") .addElement(new Element.Builder().setType(NAME).setValue("James").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("123 new Street, minneapolis mn").createElement()) .addElement(new Element.Builder().setType(PHONE).setValue("123-234-2345").setWeight(2).setThreshold(0.5).createElement()) .addElement(new Element.Builder().setType(EMAIL).setValue("james_parker@domain.com").setThreshold(0.5).createElement()) .createDocument() ); MatchService matchService = new MatchService(); Map>> result = matchService.applyMatchByDocId(incoming, existing); result.forEach((key, matches) -> matches.forEach(m -> System.out.printf("Import %s is a duplicate of existing %s (score: %.4f)\%n", m.getData().getKey(), m.getMatchedWith().getKey(), m.getResult()) ) ); // Output: Import import-1 is a duplicate of existing existing-1 (score: 0.8750) ``` ``` -------------------------------- ### Pre-processing Functions for Element Normalization Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Utilizes static factory methods to create pre-processing functions for string elements. These functions can be passed to `Element.Builder.setPreProcessingFunction()` to customize data cleaning and normalization. ```java import com.intuit.fuzzymatcher.function.PreProcessFunction; import com.intuit.fuzzymatcher.domain.Element; import static com.intuit.fuzzymatcher.domain.ElementType.*; // removeSpecialChars — strips non-alphanumeric characters Element e1 = new Element.Builder().setType(TEXT) .setValue("Hello, World! #2024") .setPreProcessingFunction(PreProcessFunction.removeSpecialChars()) // preprocessed → "Hello World 2024" .createElement(); // removeDomain — strips email domain, keeping only local part Element e2 = new Element.Builder().setType(EMAIL) .setValue("user.name+tag@company.com") .setPreProcessingFunction(PreProcessFunction.removeDomain()) // preprocessed → "user.name+tag" .createElement(); // numericValue — keeps only digits (useful for SSN, zip codes) Element e3 = new Element.Builder().setType(PHONE) .setValue("+1 (512) 234-5678") .setPreProcessingFunction(PreProcessFunction.numericValue()) // preprocessed → "15122345678" .createElement(); // Custom pre-processing function using a lambda Function customNormalizer = str -> str.replaceAll("\\bSt\\.?\\b", "Street") .replaceAll("\\bAve\\.?\\b", "Avenue"); Element e4 = new Element.Builder().setType(ADDRESS) .setValue("123 Main St. Apt 4B") .setPreProcessingFunction(customNormalizer) .createElement(); ``` -------------------------------- ### Match Service: Apply Match by Document ID Source: https://github.com/intuit/fuzzy-matcher/blob/master/README.md Use this method when you have an existing list of documents and want to identify potential duplicates within that list. ```java matchService.applyMatchByDocId(List documents) ``` -------------------------------- ### ApplyMatchByDocId: Match new records against existing list Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Checks a batch of incoming documents against an existing repository for duplicates. The `matchWith` list acts as the reference corpus. Ensure all necessary imports are included. ```java import com.intuit.fuzzymatcher.component.MatchService; import com.intuit.fuzzymatcher.domain.*; import static com.intuit.fuzzymatcher.domain.ElementType.*; // Existing system records List existing = Arrays.asList( new Document.Builder("existing-1") .addElement(new Element.Builder().setType(NAME).setValue("James Parker").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("123 new st. Minneapolis MN").createElement()) .addElement(new Element.Builder().setType(PHONE).setValue("(123) 234 2345").setWeight(2).setThreshold(0.5).createElement()) .addElement(new Element.Builder().setType(EMAIL).setValue("jparker@gmail.com").setThreshold(0.5).createElement()) .createDocument() ); // New records from a bulk import List incoming = Arrays.asList( new Document.Builder("import-1") .addElement(new Element.Builder().setType(NAME).setValue("James").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("123 new Street, minneapolis mn").createElement()) .addElement(new Element.Builder().setType(PHONE).setValue("123-234-2345").setWeight(2).setThreshold(0.5).createElement()) .addElement(new Element.Builder().setType(EMAIL).setValue("james_parker@domain.com").setThreshold(0.5).createElement()) .createDocument() ); MatchService matchService = new MatchService(); Map>> result = matchService.applyMatchByDocId(incoming, existing); result.forEach((key, matches) -> matches.forEach(m -> System.out.printf("Import %s is a duplicate of existing %s (score: %.4f)%n", m.getData().getKey(), m.getMatchedWith().getKey(), m.getResult()) ) ); // Output: Import import-1 is a duplicate of existing existing-1 (score: 0.8750) ``` -------------------------------- ### Deduplicate Data Collection with applyMatchByGroups Source: https://context7.com/intuit/fuzzy-matcher/llms.txt This variant is powerful for discovering duplicates that form chains (A≈B, B≈C), producing fully-connected clusters rather than pairwise results. Use it for comprehensive deduplication. ```java applyMatchByGroups(List) ``` -------------------------------- ### MatchService.applyMatchByDocId(Document, List) Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Convenience overload for real-time duplicate checking as a single new record is about to be persisted. ```APIDOC ## `MatchService.applyMatchByDocId(Document, List)` — Check a single new document against an existing list Convenience overload for real-time duplicate checking as a single new record is about to be persisted. ```java import com.intuit.fuzzymatcher.component.MatchService; import com.intuit.fuzzymatcher.domain.*; import static com.intuit.fuzzymatcher.domain.ElementType.*; List existingRecords = ...; // loaded from database Document newRecord = new Document.Builder("new-contact") .addElement(new Element.Builder().setType(NAME).setValue("john doe").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("546 freeman ave dallas tx 75024").createElement()) .addElement(new Element.Builder().setType(PHONE).setValue("2122232235").createElement()) .addElement(new Element.Builder().setType(EMAIL).setValue("john@doe.com").createElement()) .createDocument(); MatchService matchService = new MatchService(); Map>> result = matchService.applyMatchByDocId(newRecord, existingRecords); if (!result.isEmpty()) { result.get("new-contact").forEach(m -> System.out.printf("Potential duplicate found: %s (score: %.4f)\%n", m.getMatchedWith().getKey(), m.getResult()) ); } else { System.out.println("No duplicates found — safe to insert."); } ``` ``` -------------------------------- ### Reading and Filtering Match Results Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Shows how to iterate through all matches and extract details like source document, matched document, and similarity score. Filters for high-confidence matches with a score of 0.9 or higher. ```java import com.intuit.fuzzymatcher.domain.Match; import com.intuit.fuzzymatcher.domain.Document; Map>> result = matchService.applyMatchByDocId(documentList); // Iterate all matches result.forEach((docId, matches) -> { matches.forEach(match -> { Document source = match.getData(); // the source document Document target = match.getMatchedWith(); // the document it matched with double score = match.getResult(); // similarity score 0.0 – 1.0 System.out.printf("% -10s ↔ % -10s score=%.4f%n", source.getKey(), target.getKey(), score); }); }); // Filter to high-confidence matches only result.values().stream() .flatMap(List::stream) .filter(m -> m.getResult() >= 0.9) .forEach(m -> System.out.println("High-confidence match: " + m.getData().getKey() + " ↔ " + m.getMatchedWith().getKey())); ``` -------------------------------- ### PreProcessFunction Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Provides built-in preprocessing functions that can be applied to element values. These functions, such as `removeSpecialChars`, `removeDomain`, and `numericValue`, help normalize data before matching. ```APIDOC ## `PreProcessFunction` — Built-in pre-processing functions Static factory methods that return `Function` (or `Function` for numeric types). Pass them to `Element.Builder.setPreProcessingFunction()` to override the default behavior for any element type. ```java import com.intuit.fuzzymatcher.function.PreProcessFunction; import com.intuit.fuzzymatcher.domain.Element; import static com.intuit.fuzzymatcher.domain.ElementType.*; // removeSpecialChars — strips non-alphanumeric characters Element e1 = new Element.Builder().setType(TEXT) .setValue("Hello, World! #2024") .setPreProcessingFunction(PreProcessFunction.removeSpecialChars()) // preprocessed → "Hello World 2024" .createElement(); // removeDomain — strips email domain, keeping only local part Element e2 = new Element.Builder().setType(EMAIL) .setValue("user.name+tag@company.com") .setPreProcessingFunction(PreProcessFunction.removeDomain()) // preprocessed → "user.name+tag" .createElement(); // numericValue — keeps only digits (useful for SSN, zip codes) Element e3 = new Element.Builder().setType(PHONE) .setValue("+1 (512) 234-5678") .setPreProcessingFunction(PreProcessFunction.numericValue()) // preprocessed → "15122345678" .createElement(); // Custom pre-processing function using a lambda Function customNormalizer = str -> str.replaceAll("\\bSt\\.?\\b", "Street") .replaceAll("\\bAve\\.?\\b", "Avenue"); Element e4 = new Element.Builder().setType(ADDRESS) .setValue("123 Main St. Apt 4B") .setPreProcessingFunction(customNormalizer) .createElement(); ``` ``` -------------------------------- ### Apply Match By Groups for Transitive Document Grouping Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Groups documents by transitive similarity. If A matches B and B matches C, all three are in the same group. Returns a set of sets, where each inner set is a cluster of similar documents. ```java import com.intuit.fuzzymatcher.component.MatchService; import com.intuit.fuzzymatcher.domain.*; import static com.intuit.fuzzymatcher.domain.ElementType.*; List docs = Arrays.asList( new Document.Builder("1") .addElement(new Element.Builder().setType(NAME).setValue("Steven Wilson").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("45th Avenue 5th st.").createElement()) .createDocument(), new Document.Builder("2") .addElement(new Element.Builder().setType(NAME).setValue("John Doe").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("546 freeman ave").createElement()) .createDocument(), new Document.Builder("3") .addElement(new Element.Builder().setType(NAME).setValue("Stephen Wilkson").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("45th Ave 5th Street").createElement()) .createDocument() ); MatchService matchService = new MatchService(); Set>> groups = matchService.applyMatchByGroups(docs); System.out.println("Number of duplicate groups: " + groups.size()); // → 1 groups.forEach(group -> { System.out.println("--- Group ---"); group.forEach(m -> System.out.printf(" %s ↔ %s (score: %.4f)%n", m.getData().getKey(), m.getMatchedWith().getKey(), m.getResult())); }); // --- Group --- // 1 ↔ 3 (score: 1.0000) ``` -------------------------------- ### Add Fuzzy Matcher Maven Dependency Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Include this dependency in your Maven project to use the fuzzy-matcher library. Ensure you are using a version compatible with your Java version. ```xml com.intuit.fuzzymatcher fuzzy-matcher 1.2.2 ``` -------------------------------- ### applyMatchByDocId(Document, List) Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Checks a single new document against a list of existing documents to prevent duplicates during data ingestion. ```APIDOC ## applyMatchByDocId(Document, List) ### Description Checks a single new document against a list of existing documents to prevent duplicates during data ingestion. This is useful for real-time duplicate prevention before insertion. ### Method (Not specified, likely a static method or part of a service) ### Parameters * **newDocument** (Document) - Required - The new document to check for duplicates. * **existingDocuments** (List) - Required - The list of existing documents to compare against. ``` -------------------------------- ### applyMatchByGroups(List) Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Discovers duplicate records within a given list of documents, producing fully-connected clusters. This method is powerful for handling duplicates that form chains. ```APIDOC ## applyMatchByGroups(List) ### Description Discovers duplicate records within a given list of documents, producing fully-connected clusters. This method is powerful for handling duplicates that form chains (A≈B, B≈C). ### Method (Not specified, likely a static method or part of a service) ### Parameters * **documents** (List) - Required - The list of documents to process for discovering connected duplicate clusters. ``` -------------------------------- ### ApplyMatchByDocId: Check single new document against existing list Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Convenience overload for real-time duplicate checking as a single new record is about to be persisted. Assumes `existingRecords` are loaded from a database. ```java import com.intuit.fuzzymatcher.component.MatchService; import com.intuit.fuzzymatcher.domain.*; import static com.intuit.fuzzymatcher.domain.ElementType.*; List existingRecords = ...; // loaded from database Document newRecord = new Document.Builder("new-contact") .addElement(new Element.Builder().setType(NAME).setValue("john doe").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("546 freeman ave dallas tx 75024").createElement()) .addElement(new Element.Builder().setType(PHONE).setValue("2122232235").createElement()) .addElement(new Element.Builder().setType(EMAIL).setValue("john@doe.com").createElement()) .createDocument(); MatchService matchService = new MatchService(); Map>> result = matchService.applyMatchByDocId(newRecord, existingRecords); if (!result.isEmpty()) { result.get("new-contact").forEach(m -> System.out.printf("Potential duplicate found: %s (score: %.4f)%n", m.getMatchedWith().getKey(), m.getResult()) ); } else { System.out.println("No duplicates found — safe to insert."); } ``` -------------------------------- ### MatchService.applyMatch(List) Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Identical to `applyMatchByDocId` but returns `Map>>` keyed by the `Document` object itself rather than its string ID. Useful when you need direct access to the source document object in the result. ```APIDOC ## `MatchService.applyMatch(List)` — Deduplicate grouped by Document object Identical to `applyMatchByDocId` but returns `Map>>` keyed by the `Document` object itself rather than its string ID. Useful when you need direct access to the source document object in the result. ```java MatchService matchService = new MatchService(); Map>> result = matchService.applyMatch(documentList); result.forEach((doc, matches) -> { System.out.println("Source document key: " + doc.getKey()); matches.forEach(m -> System.out.printf(" → Matched with %s, score=%.4f%n", m.getMatchedWith().getKey(), m.getResult())); }); ``` ``` -------------------------------- ### Maven Dependency for Fuzzy Matcher Source: https://github.com/intuit/fuzzy-matcher/blob/master/README.md Include this dependency in your pom.xml to use the fuzzy-matcher library. Ensure you are using Java 11 or higher; for Java 8, use version 1.1.x. ```xml com.intuit.fuzzymatcher fuzzy-matcher 1.2.1 ``` -------------------------------- ### applyMatchByDocId(List, List) Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Performs bulk duplicate checking for multiple new documents against a list of existing documents during data ingestion. ```APIDOC ## applyMatchByDocId(List, List) ### Description Performs bulk duplicate checking for multiple new documents against a list of existing documents during data ingestion. This is suitable for batch imports. ### Method (Not specified, likely a static method or part of a service) ### Parameters * **newDocuments** (List) - Required - The list of new documents to check for duplicates. * **existingDocuments** (List) - Required - The list of existing documents to compare against. ``` -------------------------------- ### Prevent Duplicates in Bulk Imports with applyMatchByDocId Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Use this method for bulk imports to efficiently check multiple new records against an existing dataset, preventing duplicate entries. ```java applyMatchByDocId(List, List) ``` -------------------------------- ### Set Variance for Elements - Java Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Use `setVariance` to differentiate multiple elements of the same type within a single document. Only elements with matching variances are compared across documents. ```java import com.intuit.fuzzymatcher.domain.Document; import com.intuit.fuzzymatcher.domain.Element; import static com.intuit.fuzzymatcher.domain.ElementType.*; // A household record with two NAME fields — one for self, one for spouse Document household = new Document.Builder("hh-001") .addElement(new Element.Builder() .setType(NAME).setVariance("self").setValue("Tom Kelly").createElement()) .addElement(new Element.Builder() .setType(NAME).setVariance("spouse").setValue("Linda Kelly").createElement()) .createDocument(); // "self" names only match against other "self" names; "spouse" against "spouse" Document household2 = new Document.Builder("hh-002") .addElement(new Element.Builder() .setType(NAME).setVariance("self").setValue("Thomas Kelly").createElement()) .addElement(new Element.Builder() .setType(NAME).setVariance("spouse").setValue("Linda Kelley").createElement()) .createDocument(); MatchService matchService = new MatchService(); Map>> result = matchService.applyMatch( Arrays.asList(household, household2)); // → hh-001 and hh-002 will match because "self" and "spouse" variances align ``` -------------------------------- ### Apply Match By Doc ID - Java Source: https://context7.com/intuit/fuzzy-matcher/llms.txt The primary deduplication method. Finds all pairs of similar documents within the provided list. Returns a `Map>>` keyed by the source document's string ID. ```java import com.intuit.fuzzymatcher.component.MatchService; import com.intuit.fuzzymatcher.domain.Document; import com.intuit.fuzzymatcher.domain.Element; import com.intuit.fuzzymatcher.domain.Match; import static com.intuit.fuzzymatcher.domain.ElementType.*; import java.util.*; import java.util.stream.Collectors; String[][] contacts = { {"1", "Steven Wilson", "45th Avenue 5th st."}, {"2", "John Doe", "546 freeman ave"}, {"3", "Stephen Wilkson","45th Ave 5th Street"} // likely same as #1 }; List docs = Arrays.stream(contacts).map(c -> new Document.Builder(c[0]) .addElement(new Element.Builder().setType(NAME).setValue(c[1]).createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue(c[2]).createElement()) .createDocument() ).collect(Collectors.toList()); MatchService matchService = new MatchService(); Map>> result = matchService.applyMatchByDocId(docs); result.forEach((key, matches) -> matches.forEach(m -> System.out.printf("Data: %s Matched With: %s Score: %.4f\n", m.getData(), m.getMatchedWith(), m.getScore().getResult()) ) ); // Output: // Data: {[ADDRESS:'45th Avenue 5th st.'][NAME:'Steven Wilson']} // Matched With: {[ADDRESS:'45th Ave 5th Street'][NAME:'Stephen Wilkson']} Score: 1.0000 // (doc "2" has no match — result map has 2 entries for keys "1" and "3") ``` -------------------------------- ### MatchService.applyMatchByGroups Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Groups documents by transitive similarity. If document A matches B and B matches C, all three are placed in the same group. This method returns a set of sets, where each inner set represents a cluster of similar documents. ```APIDOC ## `MatchService.applyMatchByGroups(List)` — Transitive grouping of similar documents Groups documents by transitive similarity: if A matches B and B matches C, all three appear in the same group. Returns `Set>>` where each inner set represents one cluster of similar documents. ```java import com.intuit.fuzzymatcher.component.MatchService; import com.intuit.fuzzymatcher.domain.*; import static com.intuit.fuzzymatcher.domain.ElementType.*; List docs = Arrays.asList( new Document.Builder("1") .addElement(new Element.Builder().setType(NAME).setValue("Steven Wilson").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("45th Avenue 5th st.").createElement()) .createDocument(), new Document.Builder("2") .addElement(new Element.Builder().setType(NAME).setValue("John Doe").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("546 freeman ave").createElement()) .createDocument(), new Document.Builder("3") .addElement(new Element.Builder().setType(NAME).setValue("Stephen Wilkson").createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue("45th Ave 5th Street").createElement()) .createDocument() ); MatchService matchService = new MatchService(); Set>> groups = matchService.applyMatchByGroups(docs); System.out.println("Number of duplicate groups: " + groups.size()); // → 1 groups.forEach(group -> { System.out.println("--- Group ---"); group.forEach(m -> System.out.printf(" %s ↔ %s (score: %.4f)%n", m.getData().getKey(), m.getMatchedWith().getKey(), m.getResult())); }); // --- Group --- // 1 ↔ 3 (score: 1.0000) ``` ``` -------------------------------- ### ApplyMatch: Deduplicate grouped by Document object Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Identical to `applyMatchByDocId` but returns `Map>>` keyed by the `Document` object itself rather than its string ID. Useful when you need direct access to the source document object in the result. ```java MatchService matchService = new MatchService(); Map>> result = matchService.applyMatch(documentList); result.forEach((doc, matches) -> { System.out.println("Source document key: " + doc.getKey()); matches.forEach(m -> System.out.printf(" → Matched with %s, score=%.4f%n", m.getMatchedWith().getKey(), m.getResult())); }); ``` -------------------------------- ### Prevent Duplicates in Real-time with applyMatchByDocId Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Call this method to check a single new record for duplicates before insertion, ensuring data integrity during real-time ingestion. ```java applyMatchByDocId(Document, List) ``` -------------------------------- ### MatchService.applyMatchByDocId Source: https://context7.com/intuit/fuzzy-matcher/llms.txt The primary deduplication method. Finds all pairs of similar documents within the provided list. Returns a `Map>>` keyed by the source document's string ID. ```APIDOC ## `MatchService.applyMatchByDocId(List)` — Deduplicate a list of documents The primary deduplication method. Finds all pairs of similar documents within the provided list. Returns a `Map>>` keyed by the source document's string ID. ```java import com.intuit.fuzzymatcher.component.MatchService; import com.intuit.fuzzymatcher.domain.Document; import com.intuit.fuzzymatcher.domain.Element; import com.intuit.fuzzymatcher.domain.Match; import static com.intuit.fuzzymatcher.domain.ElementType.*; import java.util.*; import java.util.stream.Collectors; String[][] contacts = { {"1", "Steven Wilson", "45th Avenue 5th st."}, {"2", "John Doe", "546 freeman ave"}, {"3", "Stephen Wilkson","45th Ave 5th Street"} // likely same as #1 }; List docs = Arrays.stream(contacts).map(c -> new Document.Builder(c[0]) .addElement(new Element.Builder().setType(NAME).setValue(c[1]).createElement()) .addElement(new Element.Builder().setType(ADDRESS).setValue(c[2]).createElement()) .createDocument() ).collect(Collectors.toList()); MatchService matchService = new MatchService(); Map>> result = matchService.applyMatchByDocId(docs); result.forEach((key, matches) -> matches.forEach(m -> System.out.printf("Data: %s Matched With: %s Score: %.4f\n", m.getData(), m.getMatchedWith(), m.getScore().getResult()) ) ); // Output: // Data: {[ADDRESS:'45th Avenue 5th st.'][NAME:'Steven Wilson']} // Matched With: {[ADDRESS:'45th Ave 5th Street'][NAME:'Stephen Wilkson']} Score: 1.0000 // (doc "2" has no match — result map has 2 entries for keys "1" and "3") ``` ``` -------------------------------- ### applyMatchByDocId(List) Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Discovers duplicate records within a given list of documents. This method is suitable for deduplicating an existing data collection. ```APIDOC ## applyMatchByDocId(List) ### Description Discovers duplicate records within a given list of documents. This method is suitable for deduplicating an existing data collection. ### Method (Not specified, likely a static method or part of a service) ### Parameters * **documents** (List) - Required - The list of documents to process for deduplication. ``` -------------------------------- ### Deduplicate Data Collection with applyMatchByDocId Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Use this method to discover duplicate records within an existing data collection. It is suitable for CRMs, contact databases, or transaction logs. ```java applyMatchByDocId(List) ``` -------------------------------- ### Element.Builder.setVariance Source: https://context7.com/intuit/fuzzy-matcher/llms.txt Allows a single document to contain more than one element of the same ElementType without them being treated as duplicates. Only elements with matching variances are compared across documents. ```APIDOC ## `Element.Builder.setVariance` — Differentiate multiple elements of the same type Variance allows a single document to contain more than one element of the same `ElementType` without them being treated as duplicates. Only elements with matching variances are compared across documents. ```java import com.intuit.fuzzymatcher.domain.Document; import com.intuit.fuzzymatcher.domain.Element; import static com.intuit.fuzzymatcher.domain.ElementType.*; // A household record with two NAME fields — one for self, one for spouse Document household = new Document.Builder("hh-001") .addElement(new Element.Builder() .setType(NAME).setVariance("self").setValue("Tom Kelly").createElement()) .addElement(new Element.Builder() .setType(NAME).setVariance("spouse").setValue("Linda Kelly").createElement()) .createDocument(); // "self" names only match against other "self" names; "spouse" against "spouse" Document household2 = new Document.Builder("hh-002") .addElement(new Element.Builder() .setType(NAME).setVariance("self").setValue("Thomas Kelly").createElement()) .addElement(new Element.Builder() .setType(NAME).setVariance("spouse").setValue("Linda Kelley").createElement()) .createDocument(); MatchService matchService = new MatchService(); Map>> result = matchService.applyMatch( Arrays.asList(household, household2)); // → hh-001 and hh-002 will match because "self" and "spouse" variances align ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.