+ All Categories
Home > Documents > Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1...

Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1...

Date post: 24-May-2020
Category:
Upload: others
View: 4 times
Download: 0 times
Share this document with a friend
33
Intro Suchdienst SWBplus Fazit Literatur Auf der Suche nach der verlorenen Kataloganreicherungen Tobias Rademacher Universitätsbibliothek Leipzig 27. Juni 2012 1 / 33
Transcript
Page 1: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Auf der Suche nach der verlorenenKataloganreicherungen

Tobias Rademacher

Universitätsbibliothek Leipzig

27. Juni 2012

1 / 33

Page 2: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Gliederung

EinführungKataloganreicherungenIndexierung und Enterprise Search Platform

Integration des SuchdienstesThin Integration LayerAutomatic Testing (TDD & BDD)

Integration von SWBplusHarvestingIndexierung der SWBplus-Anreicherung

Fazit

2 / 33

Page 3: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Kataloganreicherungen

• Inhaltsverzeichnissen• Abstracts• Rezensionen• etc.

3 / 33

Page 4: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

SWBplus

• Südwestdeutscher Bibliotheksverbund• Verknüpfung von Kataloganreicherungen mit Katalogen der

Verbundbibliotheken• Digitalisierung von »Inhaltsverzeichnisse[n], Klappentexte[n]

und Rezensionen«1 (Scans)• Ziel: qualitativ ›vollwertigere‹ Recherchemöglichkeiten anbieten

können• verbundübergreifender Austausch von digitalisierten (Scans)

Beständen von Inhaltsvezeichnissen• Kooperation mit Verlagen: »Verlagsinformationen, Cover,

Leseproben etc.«2

1SWBplus 20122SWBplus 2012

4 / 33

Page 5: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

SWBplus Website

5 / 33

Page 6: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Apache SolrFeatures I

• »open source enterprise search platform«3

• Volltextsuche• Umfassende Abfragemöglichkeiten• offene Schnittstellen• Faceted Search and Filtering

3Apache Solr 20126 / 33

Page 7: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Apache SolrFeatures II

• Konfigurierbare Textanalyse (↔ Indexierung)• Rich Document Parsing → Apache Tika• offene Schnittstellen• Management Sever/Monitoring (JMX)• intern: Lucene-Engine

7 / 33

Page 8: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

SchemaSolr Schema für Kataloganreicherungen

• ›straightforward‹• Fields entsprechend Anforderungen• Deklaration von »Copy Fields«

8 / 33

Page 9: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

SchemaSolr Schema für Kataloganreicherungen

1 < f i e l d name="id" t ype=" string " i n d e x e d="true" s t o r e d="true" r e q u i r e d="true"/>2 < f i e l d name="ppn" t ype=" string " i n d e x e d="true" s t o r e d="true" r e q u i r e d="true"/>3 < f i e l d name=" abstract " t ype=" text_general " i n d e x e d="true" s t o r e d="true"/>4 < f i e l d name=" tableofcontents " t ype=" text_general " i n d e x e d="true" s t o r e d="true"/>56 <uniqueKey>i d</ uniqueKey>78 <c o p y F i e l d s o u r c e=" abstract " d e s t="text"/>9 <c o p y F i e l d s o u r c e=" tableofcontents " d e s t="text"/>

9 / 33

Page 10: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

ContentStreamingExtractingRequestHandler

• Rich Document Parsing Apache Tika (Apache PDFBox)• SolrJ ContentStreamUpdateRequest (Java-Klasse)

10 / 33

Page 11: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

ContentStreamingExtractingRequestHandler

12 S o l r S e r v e r s e r v e r = new H t t p S o l r S e r v e r (TEST_SERVER_URL ) ;3 S t r i n g hashSum = c a l c u l a t e D i g e s t F o r ( e x t r a c t a b l e C o n t e n t ) ;45 ContentStreamUpdateRequest updateRequest6 = new ContentStreamUpdateRequest ( "/ update / extract " ) ;78 updateRequest . a d d F i l e ( e x t r a c t a b l e C o n t e n t ) ;9

10 updateRequest . setParam ( " literal .id" , e x t r a c t a b l e C o n t e n t . getName ( ) ) ;11 updateRequest . setParam ( "fmap. content " , " tableofcontents " ) ; // ! ! ! !12 updateRequest . setParam ( "ppn" , t e s tMapp ing . ge t ( "ppn" ) ) ;13 updateRequest . setParam ( "id" , hashSum ) ;14 NamedList<Object> r e s p o n s e = s e r v e r . r e q u e s t ( updateRequest ) ;

11 / 33

Page 12: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

AnforderungenAnforderungen

• Schlankheit• Suchergebnis → JSON-Format

• PPN• Index selbst (jeweils für Abstracts, Inhaltsverzeichnisse)• ggf. ID (z. B. Digest des ursprünglichen Textes)

12 / 33

Page 13: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

MVCModel-View-Controller Pattern

13 / 33

Page 14: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

EvaluationEvaluation

• Solr API• Frameworks• Ruby on Rails 3.x vs. Django 1.x• Ruby 1.9.x vs. Python 2.x• → vorhandenes Know-How

14 / 33

Page 15: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

DjangoDjango Framework

• Python Web framework• MVC und DRY principle• Modularisierung & Pluggablity

15 / 33

Page 16: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Django ProjektDjango Projekt Struktur

Site

urls.py

settings.py

Catalog Enrichment Module

views.py models.py

features

abstracts.features abstracts.py

16 / 33

Page 17: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Python Solr LibrarySunburnt

• vs. Haystack → ORM/Models• ›pythonic‹• Querying API• Object-Mapping von Suchergebnissen (Python-Klasse)• erlaubt die Einschränkung einer Suche auf bestimmte

Indexfelder• Faceting• Pagination with Django

17 / 33

Page 18: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Content-negotiation & DRYRubyish

1 def i n d e x2 @people = Person . f i n d ( : a l l )34 respond_to do | fo rmat |5 fo rmat . html6 format . j s o n { r e n d e r : j s o n => @people . to_ j son }7 format . xml { r e n d e r : xml => @people . to_xml }8 end9 end

18 / 33

Page 19: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Content-negotiationContent-negotiation & Django

Pythonic

• Django-Decorators & MultiResponse class• Bennett 2008: Another take on content negotiation• Content-negotiation framework for Django4

4Oxford-University 201219 / 33

Page 20: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Content-negotiationPythonic

1 c l a s s IndexView ( JSONView , HTMLView ) :2 def get ( s e l f , r e q u e s t ) :3 # . . .4 r e s p o n s e = s e l f . r e n d e r ( r e q u e s t , contex t , ’index ’ )5 r e s p o n s e [ ’X-Renderer - Format ’ ] = r e s p o n s e . r e n d e r e r . fo rmat6 r e t u r n r e s p o n s e

20 / 33

Page 21: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

CodeView Snipplet1 c l a s s Cata logEnr i chment :

2 def __init__ ( s e l f , id , ppn , a b s t r a c t s , t a b l e o f c o n t e n t s , ∗∗ other_kwargs ) :3 s e l f . i d = i d4 s e l f . ppn = ppn5 s e l f . a b s t r a c t s = a b s t r a c t s6 s e l f . t a b l e o f c o n t e n t s = t a b l e o f c o n t e n t s78 def __repr__ ( s e l f ) :9 r e t u r n ’CatalogEnrichment ("%s", "%s") ’ % ( id , ppn )

1011 c l a s s QueryAbst rac t sV iew ( JSONView , HTMLView ) :12 def get ( s e l f , r e q u e s t ) :13 s o l r = S o l r I n t e r f a c e (SOLR_SERVER_URL)14 r e s u l t = s o l r . que ry ( r e q u e s t .GET. ge t ( ’fulltext ’ ) ) . \15 f i e l d _ l i m i t ( [ "ppn" , " abstract " , "id" ] ) . \16 e x e c u t e ( c o n s t r u c t o r=Cata logEnr i chment )17 r e s p o n s e = s e l f . r e n d e r ( r e q ue s t , \18 Context ({ "solr - result " . r e s u l t } ) ,\19 ’query - abstracts ’ )20 r e s p o n s e [ ’X-Renderer - Format ’ ] = r e s p o n s e . r e n d e r e r . fo rmat21 r e t u r n r e s p o n s e

21 / 33

Page 22: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Django TestsDjango Unit & Interation Tests

• automatisch• »test harness« → Regression testing, Refactoring• UnitTests → Mikroebene• InterationTests → intermeditär• code-zentrisch• Fixtures und Testdaten

22 / 33

Page 23: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

BDDLettuce

• User Stories/Use Cases ↔ Test-Driven Development• Falcão 2012: »BDD5 tool for python, 100 % inspired on

cucumber.«• Gherkin language → Features• Python → Steps (Implementierung)

5Behavior Driven Development23 / 33

Page 24: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

SWBplus ErnteKataloganreicherung ernten

• kein Webservice• keine (rest)-API

Lösungsansatz→ Harvasting von pdf-Dateien

24 / 33

Page 25: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

ErntearbeiterCrawler-Skript

• Datenauszug muss bekannt sein (Liste)• Crawler-Skript

• Parallelisierung der HTTP-GET-Requests• Metadatenextraktion

• Aus dem Dateinamen selbst• Selektion von HTML-Elementen via XPath/CSS-Selektoren• Optional: Fingerabdrücke sammeln (Message-Digest)

25 / 33

Page 26: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

ErntearbeiterCrawler-Skript

GET file

GET http

consume file request

process http request

26 / 33

Page 27: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Crawler-SkriptRuby

1 EM. run do2 EM: : Synchrony : : F i b e r I t e r a t o r . new ( u r l s _ s u b s e t , @concur rency ) . each do | u r l |3 u r l . s t r i p !4 beg in5 f i l e_name = URI . p a r s e ( u r l ) . path6 f i l e_name . gsub ! (/^\// , "" )7 f i l e _ r e q u e s t = EventMachine : : HttpRequest . new ( u r l ) . ge t8 c o n s u m e _ f i l e _ r e q u e s t ( f i l e _ r e q u e s t , f i l e_name , u r l , pend ing )9 un l e s s @ppn_output . empty ?

10 htm_url = u r l . gsub ! ( / \ . pdf / , ".htm" )11 htm_request = EventMachine : : HttpRequest . new ( htm_url ) . ge t12 consume_http_request ( htm_request , f i l e_name , htm_url , pend ing )13 end14 r e scue => e15 h a n d l e _ e r r o r ( e )16 end17 end18 end

27 / 33

Page 28: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

IndexierungKeeper-Skript

• Solr ExtractingRequestHandler via HTTP-Post-Requests• Skriptbasiert

• Python (httplib, twisted.web)• Ruby (net/http, em/http)• Shell (curl)

• mittels Solrj (Java Application)

28 / 33

Page 29: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Keeper-SkriptRuby

1 EM: : Synchrony : : F i b e r I t e r a t o r . new ( u r l s _ s u b s e t , @concur rency ) . each_key do2 | resource_name |3 metadata = @ppn_ l i s t [ resource_name ]4 beg in5 type = metadata [ resource_name ] . to_sym6 i f @types_se lec t ion_map . i n c l u d e _ k e y ?( type )7 pa ramete r s = b u i l d _ p a r a m e t e r s ( resource_name , type , metadata )8 s o u r c e = F i l e . j o i n ( @source_d i r , resource_name )9 i n d e x _ r e q u e s t _ u r i = "{ @solr_uri }{ @solr_extract_handler }?#{ parameters }"

10 i n d e x _ r e q u e s t =11 EventMachine : : HttpRequest . new ( i n d e x _ r e q u e s t _ u r i ) . po s t ( : f i l e => s o u r c e )12 consume_index_request ( i ndex_reque s t , source , pend ing )13 e l s e14 message = " Loremp ipsum "15 @ logge r . e r r o r ( message )16 end17 r e scue => e18 h a n d l e _ e r r o r ( e )19 end20 end

29 / 33

Page 30: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

ReflexionKritische Pfade

• Performance und Verhalten unter Last• Zeichensätze & Encoding (Multi-Language)• existierender OCR-Layer notwendig (PDF-Dateien)• Qualität des OCR-Layers

• ›ii‹ anstelle von ›ü‹ (Umlautproblematik)• ›ä‹ anstelle von ›a‹ (Diakritische Zeichen)• Ligaturen (ß)• Mixed Languages (Schritzeichen & Alphabetschrift)• Worttrennung (Hyphenation)

• ›Test early and fail often.‹

30 / 33

Page 31: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

FazitFazit

• Suchindex-Erzeugung auf Basis der Digitalisierungen vonSWBplus

• Implementierung eines eigenen (schlanken) Dienstes• SWPPlus ›Erntemaschine‹• Digitalisierung → Such-Index

31 / 33

Page 32: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Literatur I

Apache Solr (2012). url: http://lucene.apache.org/solr/(besucht am 25. 06. 2012).

Bennett, James (2008). Another take on content negotiation. url:http://is.gd/gSkIj0 (besucht am 25. 06. 2012).

Django Project (2012). url: https://www.djangoproject.com/(besucht am 25. 06. 2012).

Event Machine (2012). url:http://eventmachine.rubyforge.org/EventMachine.html(besucht am 25. 06. 2012).

Falcão, Gabriel (2012). Lettuce. url:https://www.djangoproject.com/ (besucht am 25. 06. 2012).

Gamma, Erich, Richard Helm und Ralph Johnson (2001).Entwurfsmuster. Elemente wiederverwendbarer objektorientierterSoftware. München: Addison-Wesley.

32 / 33

Page 33: Auf der Suche nach der verlorenen …Intro Suchdienst SWBplusFazitLiteratur Code View Snipplet 1 class CatalogEnrichment: 2 def __init__(self,id,ppn,abstracts,tableofcontents, ∗∗other_kwargs):

Intro Suchdienst SWBplus Fazit Literatur

Literatur II

Grigorik, Ilya (2012a). EM-HTTP-Request. url:https://github.com/igrigorik/em-http-request (besuchtam 25. 06. 2012).

– (2012b). EM-Synchrony. url:https://github.com/igrigorik/em-synchrony (besucht am25. 06. 2012).

Services, Oxford University Computing (2012). Content-negotiationframework for Django. url:https://github.com/oucs/django-conneg (besucht am25. 06. 2012).

SWBplus (2012). url: http://www.bsz-bw.de/digitalebibliothek/swbplus.html (besucht am25. 06. 2012).

33 / 33


Recommended