Domanda

Come faccio a trovare indirizzi duplicati in un database, o meglio fermare le persone già durante la compilazione del modulo?Immagino che prima sia, meglio è?

Esiste un buon modo per astrarre via, codice postale ecc. in modo da poter rilevare errori di battitura e semplici tentativi di ottenere 2 registrazioni?Piace:

Quellenstrasse 66/11 
Quellenstr. 66a-11

Sto parlando di indirizzi tedeschi...Grazie!

È stato utile?

Soluzione

Johannes:

@PConroy:Questo è stato anche il mio pensiero iniziale.la parte interessante è trovare buone regole di trasformazione per le diverse parti dell'indirizzo!Qualche buon suggerimento?

Quando lavoravamo su questo tipo di progetto in precedenza, il nostro approccio era quello di prendere il nostro corpus di indirizzi esistente (150.000 circa), quindi applicare le trasformazioni più comuni per il nostro dominio (Irlanda, quindi "Dr"->"Drive", " Rd"->"Strada", ecc.).Temo che all'epoca non esistessero risorse online complete per queste cose, quindi abbiamo finito per stilare noi stessi un elenco, controllando cose come l'elenco telefonico (a corto di spazio lì, gli indirizzi sono abbreviati in tutti i modi! ).Come ho detto prima, rimarrai stupito di quanti "duplicati" rileverai con l'aggiunta di poche regole comuni!

Recentemente mi sono imbattuto in una pagina con un argomento abbastanza completo elenco delle abbreviazioni degli indirizzi, anche se è inglese americano, quindi non sono sicuro di quanto sarebbe utile in Germania!Una rapida ricerca su Google ha mostrato un paio di siti, ma sembravano trappole di iscrizione a newsletter contenenti spam.Anche se stavo cercando su Google in inglese, quindi potresti dare un'occhiata più da vicino con le "abbreviazioni degli indirizzi tedeschi" in tedesco :)

Altri suggerimenti

Potresti usare il API di Google GeoCode

Il che in effetti fornisce risultati per entrambi i tuoi esempi, l'ho appena provato.In questo modo ottieni risultati strutturati che puoi salvare nel tuo database.Se la ricerca fallisce, chiedi all'utente di scrivere l'indirizzo in un altro modo.

Prima riesci a fermare le persone, più facile sarà a lungo termine!

Non avendo molta familiarità con lo schema database o il modulo di immissione dati, suggerirei un percorso simile al seguente:

  • avere campi distinti nel tuo db per ciascuna "parte" dell'indirizzo, ad es.via, città, codice postale, Länder, ecc.

  • avere il modulo di inserimento dati suddiviso in modo simile, ad es.strada, città, ecc

Il ragionamento alla base di quanto sopra è che ogni parte avrà probabilmente le proprie "regole" particolari per il controllo degli indirizzi leggermente modificati, ("Quellenstrasse"->"Quellenstr.", "66/11"->"66a-11" sopra) in modo che il codice di convalida possa verificare se i valori presentati per ciascun campo esistono nel rispettivo campo db.In caso contrario, puoi avere una classe che applica le regole di trasformazione per ogni dato campo (ad es."strasse" deriva da "str") e controlla nuovamente la presenza di duplicati.

Ovviamente il metodo sopra ha i suoi svantaggi:

  • può essere lento, a seconda del set di dati, lasciando l'utente in attesa

  • gli utenti potrebbero tentare di aggirare il problema inserendo l'indirizzo "Parti" nei campi sbagliati (aggiungendo il codice postale alla città, ecc.).ma per esperienza abbiamo scoperto che l'introduzione anche di un semplice controllo come quello sopra impedirà ad una grande percentuale di utenti di inserire indirizzi preesistenti.

Una volta eseguito il controllo di base, puoi cercare di ottimizzare gli accessi al database richiesti, perfezionare le regole, ecc. per soddisfare il tuo schema particolare.Potresti anche dare un'occhiata a La funzione match() di MySQL per elaborare un testo simile.

Prima di iniziare a cercare indirizzi duplicati nel tuo database, dovresti assicurarti di memorizzare gli indirizzi in un formato standard.

La maggior parte dei paesi ha un metodo standard per formattare gli indirizzi, negli Stati Uniti è il sistema USPS CASS: http://www.usps.com/ncsc/addressservices/certprograms/cass.htm

Ma la maggior parte degli altri paesi ha un servizio/standard simile.Prova questo sito per formati più internazionali:http://bitboost.com/ref/international-address-formats.html

Questo non solo aiuta a trovare duplicati, ma ti fa anche risparmiare denaro quando spedisci ai clienti (il servizio postale addebita meno se l'indirizzo è in un formato standard).

A seconda dell'applicazione, in alcuni casi potresti voler memorizzare un record di indirizzo "vanity" oltre al record di indirizzo standard.Ciò mantiene felici i tuoi clienti VIP.Un indirizzo "vanity" potrebbe essere qualcosa del tipo:

62 West Novantunesima Strada
Appartamento 4D
Manhattan, New York, NY 10001

Mentre l'indirizzo standard potrebbe assomigliare a questo:

62 W 91ST ST APT 4D
NEW YORK NY 10024-1414

Una cosa che potresti voler guardare è Soundex ricerche, che sono molto utili per errori di ortografia e contrazioni.

Questa tuttavia non è una convalida nel database, quindi potrebbe essere o meno quello che stai cercando.

Un'altra possibile soluzione (supponendo che tu abbia effettivamente bisogno di dati di indirizzo affidabili e non stai utilizzando gli indirizzi solo come un modo per prevenire account duplicati) è quella di utilizzare un servizio web di terze parti per standardizzare gli indirizzi forniti dai tuoi utenti.

Funziona in questo modo: il tuo sistema accetta l'indirizzo di un utente tramite un modulo online.Il modulo trasferisce l'indirizzo dell'utente al servizio Web di standardizzazione degli indirizzi di terze parti.Il servizio web restituisce lo stesso indirizzo ma ora con i dati standardizzati in campi indirizzo discreti e con le abbreviazioni e i formati standard applicati.La tua applicazione mostra questo indirizzo standardizzato all'utente per conferma prima di tentare di salvare i dati nel tuo DB.

Se tutti gli indirizzi utente passano attraverso una fase di standardizzazione e solo gli indirizzi standardizzati vengono salvati nel tuo DB, la ricerca di record duplicati dovrebbe essere notevolmente semplificata poiché ora stai confrontando mele con mele.

Uno di questi servizi di terze parti è Servizio interattivo di Global Address che include la Germania nell'elenco dei paesi supportati e ha anche una demo online che dimostra come funziona il loro servizio (il collegamento demo può essere trovato su quella pagina web).

C'è ovviamente uno svantaggio in termini di costi in questo approccio.Tuttavia, il lato positivo è che:

  1. non avrai bisogno di creare e mantenere i tuoi metadati di standardizzazione degli indirizzi
  2. non avrai bisogno di migliorare continuamente le routine di standardizzazione degli indirizzi e
  3. sei libero di concentrare le tue energie di sviluppo software sulle parti dell'applicazione che sono uniche per le tue esigenze

Disclaimer:Non lavoro per Global Address e non ho provato a utilizzare il loro servizio.Li cito semplicemente come esempio poiché hanno una demo online con cui puoi effettivamente giocare.

Per aggiungere una risposta alla mia domanda:

Un modo diverso per farlo è chiedere agli utenti il ​​loro numero di cellulare e inviare loro un messaggio di testo per la verifica.Ciò impedisce alla maggior parte delle persone di fare confusione con indirizzi duplicati.

Parlo per esperienza personale.(Grazie pigsback !) Hanno introdotto la conferma tramite cellulare.Questo mi ha impedito di avere 2 account!:-)

Mi rendo conto che il post originale è specifico per gli indirizzi tedeschi, ma questa è una buona domanda per gli indirizzi in generale.

Negli Stati Uniti esiste una parte dell'indirizzo chiamata codice a barre del punto di consegna.È un numero univoco di 12 cifre che identifica un singolo punto di consegna e può fungere da identificatore univoco di un indirizzo.Per ottenere questo valore ti consigliamo di utilizzare un'API del servizio Web di verifica dell'indirizzo o di standardizzazione degli indirizzi, che può costare circa $ 20 al mese a seconda del volume di richieste effettuate.

Nell'interesse della piena trasparenza, sono il fondatore di SmartyStreets.Offriamo proprio questo API del servizio Web di convalida degli indirizzi chiamato IndirizzoLive.Sei più che benvenuto a contattarmi personalmente per qualsiasi domanda tu abbia.

L'apprendimento automatico e l'intelligenza artificiale dispongono di algoritmi per trovare somiglianze tra stringhe e misure duplicate.

Il collegamento record o il compito di abbinare record equivalenti che differiscono in modo sintattico, è stato esplorato per la prima volta alla fine degli anni '50 e '60.

È possibile rappresentare ogni coppia di record utilizzando un vettore di funzionalità che descrivono la somiglianza tra i singoli campi record.

Ad esempio, rilevamento duplicato adattivo utilizzando misure di somiglianza di stringa apprendenti.Per esempio, leggi questo documento

  1. È possibile utilizzare metriche di distanza generiche o ottimizzate manualmente per stimare la somiglianza di potenziali duplicati.

  2. Puoi utilizzare algoritmi di corrispondenza dei nomi adattivi, come la metrica Jaro, che si basa sul numero e sull'ordine dei caratteri comuni tra due stringhe.

  3. Distanza basata su token e ibrida.In tali casi, possiamo convertire le stringhe S e T in token multiset (dove ogni token è una parola) e considerare le metriche di somiglianza su questi multiset.

Spesso si utilizzano vincoli in un database per garantire che i dati siano "unici" nel senso basato sui dati.

Per quanto riguarda gli "isomorfismi", penso che tu sia da solo, cioè scrivendo il codice da solo.Se nel database potresti usare un trigger.

Sto cercando una risposta indirizzata agli indirizzi degli Stati Uniti

Il problema in questione è impedire agli utenti di inserire duplicati come

Quellenstrasse 66/11 E Quellenstr. 66a-11

Ciò accade quando consenti all'utente di inserire l'indirizzo completo nella casella di input.

Esistono alcuni metodi che è possibile utilizzare per evitare ciò.

1.Formattazione uniforme utilizzando RegEx

  • È possibile richiedere agli utenti di inserire i dettagli in un formato uniforme.
  • Questo è molto efficiente anche durante le query
  • testare il valore inserito dall'utente rispetto ad alcune espressioni regolari e, se fallisce, chiedere all'utente di correggerlo.

2.Utilizzare un'API di mappa come Google Maps e chiedere all'utente di selezionare i dettagli da essa.

  • Se scegli Google Maps, puoi ottenerlo utilizzando la geocodifica inversa.

Da Guida per gli sviluppatori di Google,

Il termine geocodifica si riferisce generalmente alla traduzione di un indirizzo leggibile dall'uomo in una posizione su una mappa. Il processo che fa il contrario, traducendo una posizione sulla mappa in un indirizzo leggibile dall'uomo, è noto come geocodificazione inversa.

3.Consenti dati eterogenei come mostrato nella domanda e confrontali con formattazioni diverse.

  • Nella domanda, l'OP consente l'indirizzo in formato diverso.
  • In tal caso, puoi modificarlo in moduli diversi e verificarlo con il database per ottenere una soluzione.
  • Ciò potrebbe richiedere più tempo e il tempo dipende completamente dal numero di casi di test.

4.Dividere l'indirizzo in diverse parti e memorizzarlo in db e fornire tale modulo all'utente.

  • Ciò fornisce diversi campi per memorizzare la strada, la città, lo stato, ecc. nel database.
  • Fornisci inoltre all'utente diversi campi di input per inserire via, città, stato, ecc. in formato dall'alto verso il basso.
  • Quando l'utente accede allo stato, restringi la query per trovare duplicati solo a quello stato.
  • Quando l'utente inserisce la città, restringi il campo solo a quella città.
  • Quando l'utente entra nella strada, restringila a quella strada.

E infine

  • Quando l'utente inserisce l'indirizzo, modificalo in formati diversi e testalo rispetto al database.

Ciò è efficiente anche se il numero di casi di test può essere elevato, il numero di voci su cui eseguire il test sarà molto inferiore e quindi richiederà molto meno tempo.

Negli Stati Uniti puoi utilizzare USPS Strumento Web per la standardizzazione degli indirizzi.Verifica e normalizza gli indirizzi per te.In questo modo puoi normalizzare l'indirizzo prima di verificare se esiste già nel database.Se tutti gli indirizzi nel database sono già normalizzati, sarai in grado di individuare facilmente i duplicati.

URL di esempio:

https://production.shippingapis.com/ShippingAPI.dll?API=Verify&XML=insert_request_XML_qui

Esempio di richiesta:

<AddressValidateRequest USERID="XXXXX">
  <IncludeOptionalElements>true</IncludeOptionalElements>
  <ReturnCarrierRoute>true</ReturnCarrierRoute>
  <Address ID="0">  
    <FirmName />   
    <Address1 />   
    <Address2>205 bagwell ave</Address2>   
    <City>nutter fort</City>   
    <State>wv</State>   
    <Zip5></Zip5>   
    <Zip4></Zip4> 
  </Address>      
</AddressValidateRequest>

Risposta di esempio:

<AddressValidateResponse>
  <Address ID="0">
    <Address2>205 BAGWELL AVE</Address2>
    <City>NUTTER FORT</City>
    <State>WV</State>
    <Zip5>26301</Zip5>
    <Zip4>4322</Zip4>
    <DeliveryPoint>05</DeliveryPoint>
    <CarrierRoute>C025</CarrierRoute>
  </Address>
</AddressValidateResponse>

Altri paesi potrebbero avere le proprie API.Altre persone hanno menzionato API di terze parti che supportano più paesi che potrebbero essere utili in alcuni casi.

Poiché Google recupera suggerimenti per la ricerca, puoi cercare nei campi degli indirizzi del database

Innanzitutto, creiamo un file index.htm(l):

    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta http-equiv="Content-Language" content="en-us">
        <title>Address Autocomplete</title>
        <meta charset="utf-8">
        <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
        <script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
        <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
        <script src="//netsh.pp.ua/upwork-demo/1/js/typeahead.js"></script>
        <style>
            h1 {
                font-size: 20px;
                color: #111;
            }

            .content {
                width: 80%;
                margin: 0 auto;
                margin-top: 50px;
            }

            .tt-hint,
            .city {
                border: 2px solid #CCCCCC;
                border-radius: 8px 8px 8px 8px;
                font-size: 24px;
                height: 45px;
                line-height: 30px;
                outline: medium none;
                padding: 8px 12px;
                width: 400px;
            }

            .tt-dropdown-menu {
                width: 400px;
                margin-top: 5px;
                padding: 8px 12px;
                background-color: #fff;
                border: 1px solid #ccc;
                border: 1px solid rgba(0, 0, 0, 0.2);
                border-radius: 8px 8px 8px 8px;
                font-size: 18px;
                color: #111;
                background-color: #F1F1F1;
            }
        </style>
        <script>
            $(document).ready(function() {

                $('input.city').typeahead({
                    name: 'city',
                    remote: 'city.php?query=%QUERY'

                });

            })
        </script>

    <script>
            function register_address()
            {
                $.ajax({
                    type: "POST",
                    data: {
                        City: $('#city').val(),
                    },
                    url: "addressexists.php",
                    success: function(data)
                    {
                        if(data === 'ADDRESS_EXISTS')
                        {
                            $('#address')
                                .css('color', 'red')
                                .html("This address already exists!");
                        }

                    }
                })              
            }
        </script>
    </head>

    <body>
        <div class="content">

            <form>
                <h1>Try it yourself</h1>
                <input type="text" name="city" size="30" id="city" class="city" placeholder="Please Enter City or ZIP code">
<span id="address"></span>
            </form>
        </div>
    </body>
</html>

Ora creeremo un file city.php che aggregherà la nostra query al DB MySQL e fornirà la risposta come JSON.Ecco il codice:

<?php

//CREDENTIALS FOR DB
define ('DBSERVER', 'localhost');
define ('DBUSER', 'user');
define ('DBPASS','password');
define ('DBNAME','dbname');

//LET'S INITIATE CONNECT TO DB
$connection = mysqli_connect(DBSERVER, DBUSER, DBPASS,"DBNAME") or die("Can't connect to server. Please check credentials and try again");


//CREATE QUERY TO DB AND PUT RECEIVED DATA INTO ASSOCIATIVE ARRAY
if (isset($_REQUEST['query'])) {
    $query = $_REQUEST['query'];
    $sql = mysqli_query ($connection ,"SELECT zip, city FROM zips WHERE city LIKE '%{$query}%' OR zip LIKE '%{$query}%'");
    $array = array();
    while ($row = mysqli_fetch_array($sql,MYSQLI_NUM)) {
        $array[] = array (
            'label' => $row['city'].', '.$row['zip'],
            'value' => $row['city'],
        );
    }
    //RETURN JSON ARRAY
    echo json_encode ($array);
}

?>

e quindi impedire di salvarli nel database se trovati duplicati nella colonna della tabella

E per il tuo codice addressexists.php:

<?php//CREDENTIALS FOR DB
    define ('DBSERVER', 'localhost');
    define ('DBUSER', 'user');
    define ('DBPASS','password');
    define ('DBNAME','dbname');

    //LET'S INITIATE CONNECT TO DB
    $connection = mysqli_connect(DBSERVER, DBUSER, DBPASS,"DBNAME") or die("Can't connect to server. Please check credentials and try again");


    $city= mysqli_real_escape_string($_POST['city']); // $_POST is an array (not a function)
    // mysqli_real_escape_string is to prevent sql injection

    $sql = "SELECT username FROM ".TABLENAME." WHERE city='".$city."'"; // City must enclosed in two quotations

    $query = mysqli_query($connection,$sql);

    if(mysqli_num_rows($query) != 0)

    {
        echo('ADDRESS_EXISTS');
    }
?>

Abbina l'indirizzo agli indirizzi forniti da DET BundesPost per rilevare i duplicati.

DET probabilmente vende un CD come fanno gli Stati Uniti.Il problema diventa quindi la corrispondenza con gli indirizzi della Posta federale.Solo un lungo processo di sostituzione delle abbreviazioni con abbreviazioni approvate e simili.

Allo stesso modo negli Stati Uniti.Abbina gli indirizzi di USPostOffice (scusate, costano denaro, quindi i suoi CD non completamente aperti sono disponibili presso l'ufficio postale degli Stati Uniti) per trovare duplicati.

Questa è una vecchia domanda, ma un altro approccio è calcolare la distanza di Levenshtein dagli indirizzi e in questo modo puoi trovare quelli già esistenti che sono molto simili.Puoi vedere di più qui. Trovare indirizzi duplicati utilizzando la metrica della distanza di Levenshtein in SQL.

Secondo me, supponendo che tu abbia già molti dati sporchi nel tuo DB,

Devi costruire il tuo filtro sporco "fatto a mano" che possa rilevare al massimo l'abbreviazione tedesca ...

Ma se tratti molti dati, correrai il rischio di trovare campioni falsi positivi e veri negativi...

Infine, un lavoro semi automatizzato (macchina con assistenza umana quando la probabilità di un caso di falso positivo o vero negativo è troppo alta) sarà la soluzione migliore.

Più tratti "eccezione" (perché gli esseri umani sollevano eccezioni durante il riempimento dei dati), più il tuo filtro "fatto a mano" si adatterà alle tue esigenze.

D'altra parte, puoi anche utilizzare un servizio di verifica dell'indirizzo tedesco dal lato utente e memorizzare solo quello verificato...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top