Glitre

19.08.2010

Visualisering av mellomlagringsstrategi

Filed under: Logging,Mellomlagring,Sortering — magnusenger @ 11:34

For å kartlegge suksessen til mellomlagringen av Z39.50/SRU søk er det innført et enkelt logg-system, som skriver følgende informasjon til en ren tekst-fil:

  • Dato og tid for forespørselen
  • Hvilken side i trefflisten som be etterspurt
  • Hvilket bibliotek det ble søkt mot
  • Hva det ble søkt etter
  • Og ikke minst hvordan mellomlageret fungerte. Her brukes følgende «koder» :
    • nocache = søket ble ikke funnet i mellomlageret og et nytt søk ble utført mot den valgte Z39.50/SRU tjeneren
    • raw = søket ble funnet i mellomlageret, men ikke sortert på den måten som ble etterspurt, den opprinnelige trefflista (i MARCXML-format) ble hentet fra mellomlageret og sortert på ønsket måte
    • sorted = søket ble funnet i mellomlageret, ferdig sortert

For å gjøre det enklere å følge med på hvordan mellomlagringen fungerer er det laget en liten visualisering (kildekode) som viser innholdet i loggen og en grafisk fremstilling av forholdet mellom de tre mulige utfallene som er skissert ovenfor. Dataene oppdateres hvert 10. sekund, slik at man kan følge utviklingen i tilnærmet sanntid. (NB! Loggen vil bli tømt med ujevne mellomrom.)

Tanken er at denne loggingen og visualiseringen bare er starten på et system som skal gjøre det enkelt å overvåke bruken av en Glitre-installasjon.

12.08.2010

Mellomlagring

Filed under: Mellomlagring,Sortering — magnusenger @ 11:10

Det tar tid å hente poster fra Z39.50- og SRU-tjenere. Hvis det samme søket skal utføres to eller flere ganger med rimelig kort mellomrom er det liten vits i å hente trefflista fra tjeneren på nytt den andre (og tredje osv) gangen. Derfor har Glitre nå implementert mellomlagring (caching) av søkeresultater. Dette gjøres i to nivåer:

  1. De «rå» søkeresultatene lagres
  2. Søkeresultatene lagres etter at de har blitt sortert

Fordelen med dette er som følger: La oss si at to brukere utfører akkurat det samme søket med kort tids mellomrom, la oss kalle det Søk1 og Søk2. Søk1 medfører at postene hentes fra tjeneren og mellomlagres. Så sorteres de i tråd med brukerens ønske (eller standard sortering), og resultatet av dette mellomlagres. Når så Søk2 kommer, og ber om å få postene i samme rekkefølge som Søk1 er postene allerede sortert, og brukeren slipper å vente på at de skal bli sortert og systemet vårt slipper å bruke krefter på å gjenta sorteringen. La oss så si at den som utførte Søk2 utfører det samme søket en gang til, men ber om å få postene sortert på en annen måte. Nå er ikke mellomlageret med de sorterte postene til noen hjelp, men vi har fortsatt den opprinnelige trefflista mellomlagret og kan hente denne fra mellomlagret og sortere den etter brukerens ønske, uten at vedkommende trenger å vente på at postene skal hentes på nytt fra søketjeneren.

Hvor lang tid poster skal lagres i mellomlageret er et åpent spørsmål. Lagres de for lenge vil ikke endringer i de opprinnelige postene (nye, slettede og/eller endrede poster) reflekteres i søkeresultatene. Lagres de for kort vil ikke mellomlagringen ha noen effekt, fordi resultatene «går ut på dato» før det rekker å komme et nytt søk som kan dra nytte av det gamle. I utgangspunktet er levetiden til mellomlageret satt til et døgn, men dette kan endres gjennom konfigurasjonsvariabler. På sikt bør det antagelig implementeres et logg-system som viser hvilke søk som blir utført og i hvilken grad memmomlagringen faktisk kommer til nytte.

Mellomlagringen i Glitre bygger på PEAR-modulen Cache_Lite.

11.08.2010

Sorteringshelomvending

Filed under: Sortering — magnusenger @ 16:49

Som tidligere nevnt ble sortering først forsøkt implementert ved hjelp av XSLT. Etter å ha tenkt litt på neste trinn i prosessen, paginering av trefflista, viste det seg ganske fort at dette var en lite hensiktsmessig tilnerming, og sorteringen har derfor blitt re-implementert i PHP.

I samme runde har pagineringen av trefflista blitt implementert på en enkel måte. Problemet med måten det er gjort på er at koden som kaller opp søket ikke har noen måte å vite antallet treff på, og den må derfor prøve seg frem med page=1, page=2 osv til den får en feilmelding i retur. En løsning på den problemstillingen kommer etter hvert.

5.08.2010

Sortering med XSLT

Filed under: MARC,NORMARC,Sortering — magnusenger @ 14:41

Sortering med XSLT er nå implementert. Antagelig vil det trenges litt finpuss på fjerning av tegn fra årstall* osv, men den grunnleggende funksjonaliteten er på plass.

Kommentarer fra Twitter tyder på at andre mener det vil være raskere å implementere sorteringen i PHP (dvs plukke data fra postene og legge dem i array i PHP, sortere arrayene og så sette sammen postene i ny rekkefølge basert på denne sorteringen), men i første omgang nøyer vi oss med den nå værende løsningen. Dersom det blir tid til det senere i prosjektet kan vi komme tilbake til saken og prøve å implementere sorteringen på den foreslåtte måten. Da blir det både mulig å gjøre tester av hurtigheten til de to metodene, og tilby begge som konfigurerbare alternativer i Glitre.

* Årstall i MARC-poster er et glitrende eksempel på at de «maskinlesbare» dataene i MARC langt fra er så maskinlesbare som de burde ha vært:

I følge NORMARC inneholder 260$a «År. Dette er utgivelsesår, produksjonsår eller copyrightår.». Allerede her ser vi et problem. Vi har et årstall, men vi vet ikke egentlig hva årstallet representerer. Dette burde egentlig vært tre adskilte felt, eller det burde vært et ekstra felt/indikator som fortalte akkurat hva slags felt det egentlig er snakk om.

Et annet problem er at feltet ofte ikke inneholder rene årstall. Tilfeldige stikkprøver har avslørt følgende varianter:

  • [2003?]
  • [200-?]
  • pp1992
  • [2004]

Hvordan skal man kunne sortere disse på en fornuftig måte? Jo, man blir nødt til å skrelle bort de ekstra tegnene etter beste evne. Glitre har foreløpig løst dette på følgende vis:

<xsl:sort select="translate(datafield[@tag=260]/subfield[@code='c'], 'cop.[]', '')" data-type="text" order="{$sortOrder}"/>

Dette innebærer at alle forekomster av tegnene «cop.[]» i 260$c fjernes før sorteringen gjøres. Dersom MARC skulle vært virkelig maskinlesbart burde feltet inneholdt kun et rent årstall, og de opplysningene som de ekstra tegnene representerer burde vært kodet ved help av andre delfelt.

4.08.2010

Hvordan sortere MARC-poster?

Filed under: NORMARC,Sortering — magnusenger @ 15:59

Som tidligere nevnt har Glitre konkludert med at sortering må implementeres i Glitre, det er ikke mulig å basere seg på sortering på tjenerne som søkeresultatene hentes fra. Basert på tidligere erfaringer fra Pode er det (minst) to måter å gjøre dette på:

  • I Podes reiseplanlegger ble sorteringen gjort ved help av <xsl:sort>, før XSLT ble benyttet til videre bearbeiding av postene i MARCXML-format.
  • I Podes musikkmashup ble sorteringen gjort ved hjelp av array i PHP. Elementene det skulle sorteres på (tittel, forfatter osv) ble plukket ut av postene og brukt som nøkler i array som så ble sortert, før videre bearbeiding av postene.

Glitre vil i første omgang satse på å sortere med XSLT, dels fordi det vil være det mest elegante, dels fordi rå MARC-data skal være et av mange mulige ut-formater fra Glitre, og XSLT vil forhåpentligvis gjøre dette mulig uten at man trenger å plukke postene fra hverandre og så sette dem sammen igjen.

Hvor mange poster skal sorteres?

Filed under: Diverse,Sortering — magnusenger @ 15:27

Glitre har nå undersøkt mulighetene for sortering i norske Z39.50– og SRU-tjenere, funnet ut at den er fraværende eller sterkt mangelfull i samtlige systemer og konkludert med at det må utvikles en hjemmesnekret løsning for sortering. Dette reiser et interessant spørsmål:

Hvor mange poster skal/kan/bør/må man laste ned fra tjeneren før man sorterer? Hvis søket har gitt 10 eller 20 treff er det ikke noe problem, da laster man ned alle sammen før man sorterer. Men hva om søket gir feks 5.000 treff? Da støter man på minst to problemer:

  • Belastning på tjeneren
  • Tiden det vil ta å første laste ned og så sortere

Så hva gjør man?

  • Forteller den som satte i gang søket at her ble det for mange treff, vennligst søk mer spesifikt?Hvor skal man i så fall sette grensa for antall treff før denne meldinga vises? 100? 1.000?
  • Laster ned et begrenset antall poster og presenterer dem? I så fall: hvor mange?

Eller er det sånn at de ulike søketjenerne (Z39.50/SRU) legger begrensninger på hvor mange poster man kan hente pr søk?

SRU og sortering

Filed under: Sortering,SRU — magnusenger @ 15:23

En rask undersøkelse av SRU-tjenere tilknyttet BIBSYS og Koha viser at ingen av dem støtter sortering slik det er spesifisert i versjon 1.2 av CQL. Dermed blir Glitre nødt til å ty til hjemmesnekret sortering over hele linja.

Sorteringen skal i versjon 1.2 av CQL spesifiseres som en del av søkebegrepet i URLen:

"dinosaur" sortBy dc.date/sort.descending dc.title/sort.ascending

Hverken BIBSYS eller Koha endrer sorteringen i tråd med de sorteringeskriteriene man oppgir.

3.08.2010

Sortering med Z39.50

Filed under: Sortering,Z39.50 — magnusenger @ 11:53

En ting man veldig ofte forbinder med søk er sortering, og det er rimelig klart at Glitre bør tilby sortering av trefflister.

Sorteringskriterier

Hvilke kriterier/felter er det aktuelt å sortere på? Disse er kanskje de mest nærliggende:

  • Tittel
  • Forfatter, sortert på etternavn
  • Publikasjonsår
  • Anskaffelsesdato, slik at de aller nyeste postene havner øverst på lista, uavhengig av når dokumentet de beskriver er publisert

Er det flere kriterier man burde kunne sortere på?

Stigende/synkende

Skal man sortere kan man velge mellom stigende og synkende sortering. For de ulike kriteriene ovenfor vil det være aktuelt med litt ulik standard sortering:

  • Tittel: Stigende («A» kommer først)
  • Forfatter: Stigende («A» kommer først)
  • Publikasjonsår: Synkende (nyeste kommer først)
  • Anskaffelsesdato: Synkende (nyeste kommer først)

I tillegg vil det være aktuelt å kunne velge «det motsatte» for alle kriteriene, slik at lista snus på hodet.

Standard sortering

Hvordan bør en treffliste sorteres, dersom den som utfører søket ikke eksplisitt har bedt om en bestemt sortering? Herom strides de lærde, antagelig vil man kunne finne noen som argumenterer for at hvert enkelt av kriteriene ovenfor bør være standard. Glitre bør antagelig ta konsekvensen av dette og la standard sortering være konfigurerbart for den enkelte installasjon og/eller det enkelte søkemål.

Teknisk

Glitre baserer søkefunksjonaliteten mot Z39.50 søkemål på den frie programvarekomponenten PHP/YAZ (se også BibLabs allmenning). Denne utvidelsen til PHP inneholder blant annet en funksjon som ser høyst relevant ut i forhold til sortering, nemlig yaz_sort().

void yaz_sort ( resource $id , string $criteria )

Som vi ser tar denne funksjonen to argumenter:

  • $id er en referanse til en allerede etablert Z39.50-sesjon
  • $criteria spesifiserer hva det skal sorteres på og hvordan det skal sorteres
    • Formatet er «field1 flags1 field2 flags2 …», der
      • «field» er Bib-1 attributter eller navngitte indekser
      • «flag» angir retning og bahndling av store og små bokstaver:
        • a = sorter stigende
        • d = sorter synkende
        • i = sorter avhengig av store og små bokstaver
        • s = ta hensyn til store og små bokstaver ved sortering

Eksempler på sorteringskriterier:

  • «1=4 di» = sorter stigende på tittel, uavhengig av store og små bokstaver
  • «title di» = samme som over, men med en navngitt indeks
  • «1=31 ai» = sorter synkende etter «Date of publication» (nyeste først)

Fra kriterier til Bib-1 attributter

Nå vet vi hvilke kriterier vi ønsker å sortere på og hvordan vi ønsker å gjøre det, men det gjenstår å «mappe» kriteriene våre til Bib-1 attributter. Vi kan bruke dokumentet ATTRIBUTE SET BIB-1 (Z39.50-1995): SEMANTICS, og finne følgende (1. kolonne er navnet på indeksen, 2. kolonne er tallet som brukes for å lage feks 1=4, 3. kolonne er en beskrivelse og 4. kolonne er de MARC-feltene som er anbefalt inkludert i indeksen):

Tittel: 1=4

Title                   4  A word, phrase, character,      130, 21X-24X, 440,
                           or group of characters,         490, 730, 740, 830,
                           normally appearing in an item,  840, subfield $t
                           that names the item or the      in the following:
                           work contained in it.           400, 410, 410, 600,
                                                           610, 611, 700, 710,
                                                           711, 800, 810, 811

Forfatter

Author-name          1003  A personal or corporate author, 100, 110, 111, 400
                           or a conference or meeting      410, 411, 700, 710,
                           name.  (No subject name         711, 800, 810, 811
                           headings are included.)

Publikasjonsår

Date-publication       31  The date (usually year) in      008/07-10, 260$c
                           which a document is published.  046, 533$d

Anskaffelsesdato

Date-acquisition       32  The date when a document was    541$d
                           acquired.

Empiri

Vi har nå en ide om hva vi ønsker å sortere på, og hvordan vi ønsker å gjøre det. Spørsmålet blir da om dette lar seg gjøre i praksis? Innledende tester har gitt følgende resultat:

Aleph Bibliofil BIBSYS Koha Mikromarc Reindex Tidemann
Default sortering Kronologisk, synkende Alfabetisk på tittel Tilfeldig? Alfabetisk på tittel Tilfeldig?
Støtter yaz_sort() Ja Nei Nei Ja Nei
Navngitte attributter Ja Ja
1=1 : Personal name Ja Nei (Feilmelding)
1=4 : Title Ja Ja
1=30 : Date Ja Ja
1=31 : Date-publication Nei Nei (Usikkert hva det faktisk sorteres på)
1=32 : Date-acquisition Nei Ja
1=1003 : Author Ja Nei (Ser ut til å sortere på tittel)

NB! En oppdatert versjon av denne tabellen vil bli vedlikeholdt i BibLab sin allemenning: Z39.50, SRU og sortering.

Reindex og Tidemann er ikke testet, siden vi i skrivende stund ikke vet om noen testbare Z39.50-tjenere for disse systemene. Leverandørene er kontaktet for å avklare dette.

Vi ser ellers at det bare er Aleph og Koha som støtter funksjonaliteten i yaz_sort(), og at disse i varierende grad støtter sortering på de kriteriene vi er interessert i.

Konklusjon

Siden støtten for yaz_sort() er så dårlig som den er blir Glitre nødt til selv å implementere sortering, på ett eller annet vis. I og med at støtten for de kriteteriene vi ønsker å sortere på er dårlig selv i systemene som støtter yaz_sort() vil antagelig det beste være å se helt bort fra denne funksjonen, og implementere all sortering selv.

Kommende bloggposter vil omhandle sortering i SRU og hvordan sortering kan implementeres…

Blogg på WordPress.com.