• Intelligente suggesties, deel 1: Introductie en 'StartsWith'

    Dit is deel 1 in een serie over de techniek uit een 'intelligente' zoekbox.

    Enkele weken geleden werd mij een functioneel ontwerp in de handen gedrukt met als enige opmerking: 'kijk eens of we dit kunnen maken'. In twee weken bouwtijd was dit het resultaat. Vandaag deel 1 in een serie over de techniek die het mogelijk maakt om in fracties van een seconde intelligente suggesties te geven.

    Continue reading »

  • Video! On-the-fly zoeksuggesties: Levenshtein en Soundex in de praktijk

  • Going Solr!

    Klik voor meer informatie over de implementatie van Solr.

    De filters in de linkerkolom is een van de lastigste problemen die je tegenkomt als je een site als funda bouwt. Want hoe bereken je in 100 millisecondes hoeveel resultaten een gebruiker overhoudt als hij op een filter klikt? Dat zijn toch al snel 40 verschillende nieuwe queries!

    Op dit moment wordt bovenstaand probleem opgelost door zéér brede tabellen te gebruiken waarin we bijvoorbeeld de volgende velden hebben:

    Adres  | ind_Opp_100_150 | ind_Opp_150_200 | ind_Zwembad |
    Bla 1  | 1               | 0               | 1           |
    Bla 2  | 0               | 1               | 0           |

    Door al dit soort velden te hebben kan je snel bepalen welk deel van je set een oppervlakte heeft tussen de 100 en 150 m2 ( COUNT(ind_Opp_100_150) ).

    Continue reading »

  • NHibernate vs. Entity Framework

    We gebruiken sinds de laatste rewrite van onze codebase (2006) NHibernate als OR Mapper, maar na ruim vier jaar is nu het besef wel gekomen dat we eens zouden moeten upgraden, daar we nu nog op NHibernate 1.04 draaien (2.1.2 is nu uit, en 3.0 is in beta). Daarom gisteren een kennissessie [1] gehad waarin we eens bespraken welke richting we uit wilden. Bij NHibernate blijven of toch naar Entity Framework.
    [1] Gooi een sloot developers met eten en alcohol in een groen hok en wacht tot ze het eens zijn.

    Continue reading »

  • Custom Attributes op enum's

    Nogal vaak zie ik code in een MVC Controller staan als:

    public enum Pagina
    {
         [UrlPart("")]
         Index,
         [UrlPart("about-us")]
         OverOns,
    }

    Waarbij er acties zijn als:

    public void MaakLink (Pagina targetPagina)
    {
         string urlPart = ...;
         // hierboven moeilijke code om 'UrlPart' attribute te vinden
         // op de huidige waarde van de enum
    }

    Daarom vandaag een kleine snippet, die eenvoudig een attribute kan uitlezen van een enum, waarbij de syntax als volgt wordt:

    string urlPart = targetPagina.GetCustomAttribute<UrlPartAttribute>().EenProperty;

    Continue reading »

  • Typfouten, Levenshtein en Burkhard-Keller trees

    Momenteel nog aan het werk aan een project waar ik al eerder helemaal los op ging, alwaar ik vandaag aankwam op de mogelijkheid van typfouten.

    Levenshtein distance
    De levenshtein distance is het minimale aantal bewerkingen dat nodig is om van het ene woord naar het andere woord te komen.

    1: Amsterdam
    2: Amsteldam
    
    A m s t e r d a m
              ^
    A m s t e   d a m

    In bovenstaand geval dus één mutatie. Netjes van wikipedia gejat is dit voorbeeld, van kitten -> sitting:

    1. kitten -> sitten (substitution of 'k' with 's')
    2. sitten -> sittin (substitution of 'e' with 'i')
    3. sittin -> sitting (insert 'g' at the end).


    Waar is het goed voor?
    We kunnen veel met Soundex en alternatieve woorden, maar fuzzy matching is daarmee niet mogelijk. Door alle plaatsen / straten / etc. te vinden die een afstand van één hebben tot de zoekterm kan je vrij eenvoudig een lijst met alternatieven geven (natuurlijk samen met Soundex).

    Continue reading »

  • Generic retry

    Wanneer je calls naar externe sources doet (webservices, database, etc.) kan het voorkomen dat je hier een retry-mechanisme voor nodig hebt. In plaats van deze logica telkens opnieuw schrijven, zou het mooi zijn om dit generiek op te lossen!

    try {
        // doe Dao.GetDataset() maximaal 3 keer met 200 ms. pauze ertussen
        // en gooi een exception als het na 3 keer nog niet gelukt is.
        var dataSet = Actions.Retry( ()=> Dao.GetDataset(), 3, 200, true);
    } catch (Exception ex) {
         // 3 keer geprobeerd, 3 keer gefaald :-o
    }


    Implementatie
    Fairly simple eigenlijk (en een mooie reden om weer eens een goto te gebruiken!):

    Continue reading »

  • Single byte string in C#

    Definitie van een string
    In .NET is een string een verzameling karakters in Unicode. Hierdoor zijn er twee bytes per karakter nodig, plus twee bytes voor het aantal karakters in de string.

    // de string "A" staat in memory als de volgende 4 bytes:
    00 01 00 41
    // twee bytes met het getal 1, voor het aantal elementen (1 dus)
    // twee bytes met de code voor de letter, in dit geval 0x41

    Voordeel hiervan is dat bijna alle karakters in een string kunnen voorkomen. Nadeel is dat wanneer je alleen 'eenvoudige' karakters gebruikt (geen fancy tekens als á of U+263A) dat je twee keer zoveel geheugen alloceert dan eigenlijk nodig is. Normaal geen enkel probleem.

    Maar als geheugengebruik kritisch is?
    Wanneer je geheugengebruik een belangrijk punt van je applicatie is, en er bovendien veel (en ik bedoel hier véél) strings hebt, dan kan het geheugengebruik een probleem worden. Oplossing is om je strings op te slaan als arrays van 'bytes' in plaats van 'char'. Een byte heeft namelijk een width van 1 byte (what's in a name). Je kunt dan alleen wel maximaal 255 verschillende karakters gebruiken in je strings.

    Continue reading »

  • Expression Trees - Espresso voor je code!

    Eerder gepubliceerd als Expression Trees in .NET Magazine Q1 2010. Volledige artikel (PDF)

    De in het .Net framework 3.5 geïntroduceerde ‘expression trees’, zijn absoluut het Microsoft equivalent van DeLonghi’s famous espresso: goed gedoseerd levert het een ongelooflijke boost, maar een kopje teveel en je stuitert alle kanten op.

    In dit artikel gaan we in op de vraag wat expression trees zijn en hoe ze delen van je code tot honderd keer sneller kunnen maken. Laten we bij het begin beginnen: wat zijn expressions eigenlijk? Wellicht het meest eenvoudige stuk code demonstreert dit het beste:

    Continue reading »

  • Diakritische tekens en Soundex in .NET

    In Nederland kennen we zo'n 240.000 geografische entiteiten (straten, buurten, plaatsen, gemeentes, etc.) die gebruik maken van NEN-norm 5825 voor de officiële schrijfwijze. Een norm waarin géén diakritische tekens mogen worden gebruikt. So far so good.

    Wikipedia over diakrieten: Een diakritisch teken is een teken dat boven, onder of door een letter gezet wordt en nodig is voor de uitspraak. Met diakritische tekens kunnen verschillende aspecten van de uitspraak worden aangegeven. Voorbeelden hiervan zijn de tekens op é, â, ö.

    Zelfde data, andere schrijfwijze?
    So far so good, tot het CBS met een nieuwe aanlevering van buurtinformatie komt. Een groot Excel document waarin ze de schrijfwijze van buurten zoals de gemeente deze hanteert overnemen; waar uiteraard wél diakritische tekens kunnen voorkomen. Gevolg: problemen bij het koppelen van de nieuwe CBS-data, aan onze bestaande data.

    Normalisatietijd dus!

    Continue reading »