Zoeken en Indexering

Overzicht

Het zoeken en indexeringsysteem van Wasstraat Archeologische Data biedt krachtige, snelle queryopties over het hele gegevensreservoir. Dit onderdeel is bewust gemaakt voor polymorfische gegevens en multidimensionale zoekmogelijkheden.

Kernfunctionaliteiten

1. Fulltext-Zoeking

Geavanceerde tekstzoeking over alle ongestructureerde velden:

# Voorbeelden van fulltext-queries
results = search.fulltext("handgevormd aardewerk Amsterdam")
results = search.fulltext("Bronstijd fragment")
results = search.fulltext("potscherf kwarts")

Zoekmechanisme

Zoekinvoer: "handgevormd aardewerk"
            │
            ▼
┌───────────────────────────────────┐
│ Tokenisering                      │
│ "handgevormd" | "aardewerk"       │
└────────────┬──────────────────────┘
             │
             ▼
┌───────────────────────────────────┐
│ Lemmatisering (Nederlands)        │
│ "handgevormd" → "hand"+"gevormd"  │
│ "aardewerk" → "aard"+"werk"       │
└────────────┬──────────────────────┘
             │
             ▼
┌───────────────────────────────────┐
│ Index Lookup                      │
│ Alle documenten met beide termen  │
└────────────┬──────────────────────┘
             │
             ▼
┌───────────────────────────────────┐
│ Ranking (BM25 algoritme)          │
│ • Termfrequentie                  │
│ • Inverse documentfrequentie      │
│ • Documentlengte normalisatie     │
└────────────┬──────────────────────┘
             │
             ▼
┌───────────────────────────────────┐
│ Zoekresultaten (gesorteerd)       │
└───────────────────────────────────┘

2. Fuzzy-Zoeking

Tolerantie voor typografische fouten en spellingsvarianties:

Zoekinvoer: "potscherf"
            
            ├─→ Exacte match: "potscherf" (score: 1.0)
            
            ├─→ Fuzzy matches:
               ├─ "potscherven" (1 toevoeging) - score: 0.85
               ├─ "potsherd" (Engels) - score: 0.80
               ├─ "potscherp" (typografiefout) - score: 0.75
               └─ "pottenscherf" (spellingsvariant) - score: 0.70
            
            └─→ Gefilterde resultaten (score > 0.70)

Fuzzy-Algoritme

Het systeem gebruikt een combinatie van:

  • Levenshtein-afstand: Minste aantal edits nodig
  • Jaro-Winkler: Voor gelijkaardige prefixteksten
  • N-gram matching: Voor fragmentaire overeenkomsten

3. AI-Gebaseerde Indexering (In Ontwikkeling)

Geavanceerde semantische indexering met machine learning:

Vectorrepresentatie van Documenten:

Artefact 1: "handgevormd aardewerk fragment"
                    │
                    ▼
        ┌──────────────────────┐
        │  NLP-Model (BERT)    │
        └──────────┬───────────┘
                   │
                   ▼
        Semantische vector [n-dimensies]
        Bijv: [0.45, 0.82, 0.12, ..., 0.63]

Artefact 2: "hand crafted pottery shard"
                    │
                    ▼
        ┌──────────────────────┐
        │  NLP-Model (BERT)    │
        └──────────┬───────────┘
                   │
                   ▼
        Semantische vector [n-dimensies]
        Bijv: [0.43, 0.84, 0.11, ..., 0.61]

Gelijkenis-berekening (cosinus-overeenkomst):
cos(vector_1, vector_2) = 0.98 (zeer gelijk!)

Voordelen

  • Begrijpt semantische betekenis
  • Werkt in meerdere talen
  • Vindt conceptueel soortgelijke items
  • Tolerant voor variaties

Indexering Componenten

1. Fulltext Index

{
  "index_type": "fulltext",
  "index_name": "artefacten_text",
  "velden": [
    "beschrijving",
    "materiaal_omschrijving",
    "locatie_notities",
    "onderzoeksnota's"
  ],
  "taal": "nederlands",
  "analyzer": {
    "type": "standard",
    "stopwords": ["de", "het", "een", "van"]
  },
  "parameters": {
    "min_term_length": 3,
    "max_term_length": 100
  }
}

2. Fuzzy Index

{
  "index_type": "fuzzy",
  "index_name": "artefacten_fuzzy",
  "velden": [
    "object_id",
    "artefact_type",
    "materiaal",
    "periode"
  ],
  "fuzzy_parameters": {
    "max_edits": 2,
    "prefix_length": 1,
    "boost": 1.5
  }
}

3. Geografische Index

{
  "index_type": "geospatial",
  "index_name": "artefacten_geo",
  "velden": [
    "locatie.coördinaten"
  ],
  "type": "geohash",
  "precision": 10
}

4. Chronologische Index

{
  "index_type": "temporal",
  "index_name": "artefacten_chrono",
  "velden": [
    "discovery_date",
    "periode_start",
    "periode_eind"
  ],
  "resolutie": "dag"
}

Querytypen

Eenvoudige Queries

# Fulltext-zoeking
search.find_text("handgevormd aardewerk")

# Fuzzy-zoeking
search.find_fuzzy("potscherf", tolerance=0.8)

# Gelijk aan
search.equal("artefact_type", "aardewerk")

Geavanceerde Queries

# Combinatie met operatoren
search.find({
  "must": [
    {"text": "aardewerk"},
    {"equal": {"periode": "Bronstijd"}}
  ],
  "should": [
    {"text": "handgevormd"},
    {"text": "ingegraven motief"}
  ],
  "must_not": [
    {"equal": {"status": "verloren"}}
  ]
})

# Geografische range-query
search.find_geo_within(
  center=[52.3702, 4.8952],
  radius_m=5000,
  must=[{"period": "Bronstijd"}]
)

# Chronologische range-query
search.find_temporal(
  date_start="2000-01-01 vC",
  date_end="500-01-01 vC",
  must=[{"material": "aarde"}]
)

Classificatie van resultaten in kategoriën:

results = search.find_text("aardewerk")
results.facets = {
  "periode": {
    "Bronstijd": 245,
    "IJzertijd": 187,
    "Romeins": 92,
    "Middeleeuwen": 34
  },
  "materiaal": {
    "aarde": 487,
    "steen": 12,
    "andere": 59
  },
  "status": {
    "compleet": 82,
    "fragmentair": 437,
    "verloren": 39
  }
}

Architectuur

┌─────────────────────────────────────────┐
│  SingleStore Gegevens               │
└────────────┬────────────────────────────┘
             │
             ▼
┌─────────────────────────────────────────┐
│  Indexering Pipeline                │
├─────────────────────────────────────────┤
│ 1. Data Extraction                  │
│    (Velden selecteren)              │
│                                         │
│ 2. Preprocessing                    │
│    (Tokenisering, Normalisatie)     │
│                                         │
│ 3. Indexing                         │
│    (Fulltext, Fuzzy, Geo, etc.)     │
│                                         │
│ 4. Indexen Persistentie             │
│    (Opslag in Search Engine)        │
└────────────┬────────────────────────────┘
             │
         ┌───┴───┬───────┬──────┐
         │       │       │      │
         ▼       ▼       ▼      ▼
    Fulltext  Fuzzy   Geo   Chrono
    Index    Index   Index  Index
         │       │       │      │
         └───┬───┴───────┴──────┘
             │
             ▼
┌─────────────────────────────────────────┐
│  Query Engine                       │
│  ├─ Query Parser                    │
│  ├─ Query Optimizer                 │
│  └─ Results Ranking                 │
└────────────┬────────────────────────────┘
             │
             ▼
┌─────────────────────────────────────────┐
│  Zoekresultaten                     │
│  (Gesorteerd, Gefacetteerd)         │
└─────────────────────────────────────────┘

Polymorfische Gegevens

Een van de kernuitdagingen is zoeken in polymorfische data. Wasstraat behandelt dit door:

{
  "universal_fields": [
    "object_id",
    "beschrijving",
    "locatie",
    "discovery_date",
    "periode"
  ],
  "type_specific_fields": {
    "aardewerk": ["vorm", "decoratie", "branding"],
    "werktuig": ["functie", "schijf_techniek"],
    "structuur": ["type", "afmetingen", "diepte"]
  }
}

Alle universele velden worden standaard geïndexeerd. Type-specifieke velden worden optioneel geïndexeerd.

Performance Optimalisering

Indexen Caching

┌────────────────────────────────┐
│  Populaire Queries Cache       │
├────────────────────────────────┤
│ Query 1: "Bronstijd"           │
│ Hit Rate: 87%                  │
│ Avg Response: 15ms             │
│                                │
│ Query 2: "Amsterdam aardewerk" │
│ Hit Rate: 62%                  │
│ Avg Response: 45ms             │
│                                │
│ Query 3: "Handgevormd"         │
│ Hit Rate: 54%                  │
│ Avg Response: 127ms            │
│                                │
│ (Minder hits = indexering      │
│  moet geoptimaliseerd worden)  │
└────────────────────────────────┘

Incrementele Indexering

Bij wijzigingen worden alleen gemodificeerde velden opnieuw geïndexeerd:

Record Wijziging:
  Field 1 (geïndexeerd): gewijzigd
  Field 2 (geïndexeerd): ongewijzigd
  Field 3 (niet geïndexeerd): gewijzigd

→ Alleen Field 1 wordt opnieuw geïndexeerd
→ Field 2 behoudt bestaande index
→ Field 3 vereist geen indexering

Best Practices

Indexoptimalisatie

Niet alle velden hoeven te worden geïndexeerd. Over-indexering verslechtert performance.

  • Indexeer alleen veelgebruikte zoekvelden
  • Monitor query-performance regelmatig
  • Verwijder ongebruikte indexen
  • Test grote query's op testomgeving

Zoekinstructies

Gebruikers kunnen beste resultaten behalen door: - Nauwkeurige zoekwoorden gebruiken - Operators combineren (AND, OR, NOT) - Filters toe te passen voor nauwkeurigheid - Faceten te gebruiken voor verfijning

Integratie

Het zoeken en indexeringssysteem werkt samen met:

  • SingleStore: Databestand voor indexering
  • Validatie: Indexeert alleen gevalideerde records
  • Crossviews: Kan "soortgelijke items" suggeren
  • Configuratie: Maakt aangepaste indexen mogelijk