dada3511a65ec05e444413bc8a59acdd4f8068ce
[idzebra-moved-to-github.git] / doc / architecture.xml
1  <chapter id="architecture">
2   <!-- $Id: architecture.xml,v 1.1 2006-01-18 14:00:54 marc Exp $ -->
3   <title>Overview of Zebra Architecture</title>
4   
5
6   <sect1 id="local-representation">
7    <title>Local Representation</title>
8
9    <para>
10     As mentioned earlier, Zebra places few restrictions on the type of
11     data that you can index and manage. Generally, whatever the form of
12     the data, it is parsed by an input filter specific to that format, and
13     turned into an internal structure that Zebra knows how to handle. This
14     process takes place whenever the record is accessed - for indexing and
15     retrieval.
16    </para>
17
18    <para>
19     The RecordType parameter in the <literal>zebra.cfg</literal> file, or
20     the <literal>-t</literal> option to the indexer tells Zebra how to
21     process input records.
22     Two basic types of processing are available - raw text and structured
23     data. Raw text is just that, and it is selected by providing the
24     argument <emphasis>text</emphasis> to Zebra. Structured records are
25     all handled internally using the basic mechanisms described in the
26     subsequent sections.
27     Zebra can read structured records in many different formats.
28     <!--
29     How this is done is governed by additional parameters after the
30     "grs" keyword, separated by "." characters.
31     -->
32    </para>
33   </sect1>
34
35   <sect1 id="workflow">
36    <title>Indexing and Retrieval Workflow</title>
37
38   <para>
39    Records pass through three different states during processing in the
40    system.
41   </para>
42
43   <para>
44
45    <itemizedlist>
46     <listitem>
47      
48      <para>
49       When records are accessed by the system, they are represented
50       in their local, or native format. This might be SGML or HTML files,
51       News or Mail archives, MARC records. If the system doesn't already
52       know how to read the type of data you need to store, you can set up an
53       input filter by preparing conversion rules based on regular
54       expressions and possibly augmented by a flexible scripting language
55       (Tcl).
56       The input filter produces as output an internal representation,
57       a tree structure.
58
59      </para>
60     </listitem>
61     <listitem>
62
63      <para>
64       When records are processed by the system, they are represented
65       in a tree-structure, constructed by tagged data elements hanging off a
66       root node. The tagged elements may contain data or yet more tagged
67       elements in a recursive structure. The system performs various
68       actions on this tree structure (indexing, element selection, schema
69       mapping, etc.),
70
71      </para>
72     </listitem>
73     <listitem>
74
75      <para>
76       Before transmitting records to the client, they are first
77       converted from the internal structure to a form suitable for exchange
78       over the network - according to the Z39.50 standard.
79      </para>
80     </listitem>
81
82    </itemizedlist>
83
84   </para>
85   </sect1>
86
87
88   <sect1 id="maincomponents">
89    <title>Main Components</title>
90    <para>
91     The Zebra system is designed to support a wide range of data management
92     applications. The system can be configured to handle virtually any
93     kind of structured data. Each record in the system is associated with
94     a <emphasis>record schema</emphasis> which lends context to the data
95     elements of the record.
96     Any number of record schemas can coexist in the system.
97     Although it may be wise to use only a single schema within
98     one database, the system poses no such restrictions.
99    </para>
100    <para>
101     The Zebra indexer and information retrieval server consists of the
102     following main applications: the <literal>zebraidx</literal>
103     indexing maintenance utility, and the <literal>zebrasrv</literal>
104     information query and retireval server. Both are using some of the
105     same main components, which are presented here.
106    </para>    
107    <para>    
108     This virtual package installs all the necessary packages to start
109     working with IDZebra - including utility programs, development libraries,
110     documentation and modules.
111      <literal>idzebra1.4</literal>
112   </para>    
113    
114    <sect2 id="componentcore">
115     <title>Core Zebra Module Containing Common Functionality</title>
116     <para>
117      - loads external filter modules used for presenting
118      the recods in a search response.
119      - executes search requests in PQF/RPN, which are handed over from
120      the YAZ server frontend API   
121      - calls resorting/reranking algorithms on the hit sets
122      - returns - possibly ranked - result sets, hit
123      numbers, and the like internal data to the YAZ server backend API.
124     </para>
125     <para> 
126      This package contains all run-time libraries for IDZebra.
127      <literal>libidzebra1.4</literal> 
128      This package includes documentation for IDZebra in PDF and HTML.
129      <literal>idzebra1.4-doc</literal> 
130      This package includes common essential IDZebra configuration files
131      <literal>idzebra1.4-common</literal>
132     </para>
133    </sect2>
134    
135
136    <sect2 id="componentindexer">
137     <title>Zebra Indexer</title>
138     <para>
139      the core Zebra indexer which
140      - loads external filter modules used for indexing data records of
141      different type. 
142      - creates, updates and drops databases and indexes
143     </para>    
144     <para>    
145      This package contains IDZebra utilities such as the zebraidx indexer
146      utility and the zebrasrv server.
147      <literal>idzebra1.4-utils</literal>
148     </para>
149    </sect2>
150
151    <sect2 id="componentsearcher">
152     <title>Zebra Searcher/Retriever</title>
153     <para>
154      the core Zebra searcher/retriever which
155     </para>    
156     <para>    
157      This package contains IDZebra utilities such as the zebraidx indexer
158      utility and the zebrasrv server, and their associated man pages.
159      <literal>idzebra1.4-utils</literal>
160     </para>
161    </sect2>
162
163    <sect2 id="componentyazserver">
164     <title>YAZ Server Frontend</title>
165     <para>
166      The YAZ server frontend is 
167      a full fledged stateful Z39.50 server taking client
168      connections, and forwarding search and scan requests to the 
169      Zebra core indexer.
170     </para>
171     <para>
172      In addition to Z39.50 requests, the YAZ server frontend acts
173      as HTTP server, honouring
174      SRW SOAP requests, and SRU REST requests. Moreover, it can
175      translate inco ming CQL queries to PQF/RPN queries, if
176      correctly configured. 
177     </para>
178     <para>
179     YAZ is a toolkit that allows you to develop software using the
180     ANSI Z39.50/ISO23950 standard for information retrieval.
181     SRW/SRU
182     <literal>libyazthread.so</literal>
183     <literal>libyaz.so</literal>
184     <literal>libyaz</literal>
185     </para>
186    </sect2>
187    
188    <sect2 id="componentmodules">
189     <title>Record Models and Filter Modules</title>
190     <para>
191       all filter modules which do indexing and record display filtering:
192 This virtual package contains all base IDZebra filter modules. EMPTY ???
193      <literal>libidzebra1.4-modules</literal>
194     </para>
195
196    <sect3 id="componentmodulestext">
197     <title>TEXT Record Model and Filter Module</title>
198     <para>
199       Plain ASCII text filter
200      <!--
201      <literal>text module missing as deb file<literal>
202      -->
203     </para>
204    </sect3>
205
206    <sect3 id="componentmodulesgrs">
207     <title>GRS Record Model and Filter Modules</title>
208     <para>
209    Chapter <xref linkend="record-model"/>
210
211      - grs.danbib     GRS filters of various kind (*.abs files)
212 IDZebra filter grs.danbib (DBC DanBib records)
213   This package includes grs.danbib filter which parses DanBib records.
214   DanBib is the Danish Union Catalogue hosted by DBC
215   (Danish Bibliographic Centre).
216      <literal>libidzebra1.4-mod-grs-danbib</literal>
217
218
219      - grs.marc
220      - grs.marcxml
221   This package includes the grs.marc and grs.marcxml filters that allows
222   IDZebra to read MARC records based on ISO2709.
223
224      <literal>libidzebra1.4-mod-grs-marc</literal>
225
226      - grs.regx
227      - grs.tcl        GRS TCL scriptable filter
228   This package includes the grs.regx and grs.tcl filters.
229      <literal>libidzebra1.4-mod-grs-regx</literal>
230
231
232      - grs.sgml
233      <literal>libidzebra1.4-mod-grs-sgml not packaged yet ??</literal>
234
235      - grs.xml
236   This package includes the grs.xml filter which uses Expat to
237   parse records in XML and turn them into IDZebra's internal grs node.
238      <literal>libidzebra1.4-mod-grs-xml</literal>
239     </para>
240    </sect3>
241
242    <sect3 id="componentmodulesalvis">
243     <title>ALVIS Record Model and Filter Module</title>
244      <para>
245       - alvis          Experimental Alvis XSLT filter
246       <literal>mod-alvis.so</literal>
247       <literal>libidzebra1.4-mod-alvis</literal>
248      </para>
249     </sect3>
250
251    <sect3 id="componentmodulessafari">
252     <title>SAFARI Record Model and Filter Module</title>
253     <para>
254      - safari
255      <!--
256      <literal>safari module missing as deb file<literal>
257      -->
258     </para>
259    </sect3>
260
261    </sect2>
262
263    <sect2 id="componentconfig">
264     <title>Configuration Files</title>
265     <para>
266      - yazserver XML based config file
267      - core Zebra ascii based config files
268      - filter module config files in many flavours  
269      - CQL to PQF ascii based config file
270     </para>
271    </sect2>
272    
273   </sect1>
274
275   <!--
276
277
278   <sect1 id="cqltopqf">
279    <title>Server Side CQL To PQF Conversion</title>
280    <para>
281   The cql2pqf.txt yaz-client config file, which is also used in the
282   yaz-server CQL-to-PQF process, is used to to drive
283   org.z3950.zing.cql.CQLNode's toPQF() back-end and the YAZ CQL-to-PQF
284   converter.  This specifies the interpretation of various CQL
285   indexes, relations, etc. in terms of Type-1 query attributes.
286  
287   This configuration file generates queries using BIB-1 attributes.
288   See http://www.loc.gov/z3950/agency/zing/cql/dc-indexes.html
289   for the Maintenance Agency's work-in-progress mapping of Dublin Core
290   indexes to Attribute Architecture (util, XD and BIB-2)
291   attributes.
292
293   a) CQL set prefixes  are specified using the correct CQL/SRW/U
294   prefixes for the required index sets, or user-invented prefixes for
295   special index sets. An index set in CQL is roughly speaking equivalent to a
296   namespace specifier in XML.
297
298   b) The default index set to be used if none explicitely mentioned
299
300   c) Index mapping definitions of the form
301
302       index.cql.all  = 1=text
303
304   which means that the index "all" from the set "cql" is mapped on the
305   bib-1 RPN query "@attr 1=text" (where "text" is some existing index
306   in zebra, see indexing stylesheet) 
307
308   d) Relation mapping from CQL relations to bib-1 RPN "@attr 2= " stuff
309
310   e) Relation modifier mapping from CQL relations to bib-1 RPN "@attr
311   2= " stuff 
312
313   f) Position attributes
314
315   g) structure attributes
316
317   h) truncation attributes
318
319   See
320   http://www.indexdata.com/yaz/doc/tools.tkl#tools.cql.map for config
321   file details.
322
323
324    </para>
325   </sect1>
326
327
328   <sect1 id="ranking">
329    <title>Static and Dynamic Ranking</title>
330    <para>
331       Zebra uses internally inverted indexes to look up term occurencies
332   in documents. Multiple queries from different indexes can be
333   combined by the binary boolean operations AND, OR and/or NOT (which
334   is in fact a binary AND NOT operation). To ensure fast query execution
335   speed, all indexes have to be sorted in the same order.
336
337   The indexes are normally sorted according to document ID in
338   ascending order, and any query which does not invoke a special
339   re-ranking function will therefore retrieve the result set in document ID
340   order.
341
342   If one defines the 
343  
344     staticrank: 1 
345
346   directive in the main core Zebra config file, the internal document
347   keys used for ordering are augmented by a preceeding integer, which
348   contains the static rank of a given document, and the index lists
349   are ordered 
350     - first by ascending static rank
351     - then by ascending document ID.
352
353   This implies that the default rank "0" is the best rank at the
354   beginning of the list, and "max int" is the worst static rank.
355  
356   The "alvis" and the experimental "xslt" filters are providing a
357   directive to fetch static rank information out of the indexed XML
358   records, thus making _all_ hit sets orderd after ascending static
359   rank, and for those doc's which have the same static rank, ordered
360   after ascending doc ID.
361   If one wants to do a little fiddeling with the static rank order,
362   one has to invoke additional re-ranking/re-ordering using dynamic 
363   reranking or score functions. These functions return positive
364   interger scores, where _highest_ score is best, which means that the
365   hit sets will be sorted according to _decending_ scores (in contrary
366   to the index lists which are sorted according to _ascending_ rank
367   number and document ID) 
368
369
370   Those are defined in the zebra C source files 
371
372    "rank-1" : zebra/index/rank1.c  
373               default TF/IDF like zebra dynamic ranking
374    "rank-static" : zebra/index/rankstatic.c
375               do-nothing dummy static ranking (this is just to prove
376               that the static rank can be used in dynamic ranking functions)  
377    "zvrank" : zebra/index/zvrank.c
378               many different dynamic TF/IDF ranking functions 
379
380    The are in the zebra config file enabled by a directive like:
381
382    rank: rank-static
383
384    Notice that the "rank-1" and "zvrank" do not use the static rank
385    information in the list keys, and will produce the same ordering
386    with our without static ranking enabled.
387
388    The dummy "rank-static" reranking/scoring function returns just
389      score = max int - staticrank
390    in order to preserve the ordering of hit sets with and without it's
391    call.
392
393    Obviously, one wants to make a new ranking function, which combines
394    static and dynamic ranking, which is left as an exercise for the
395    reader .. (Wray, this is your's ...)
396
397
398    </para>
399
400
401    <para>
402     yazserver frontend config file
403
404   db/yazserver.xml 
405
406   Setup of listening ports, and virtual zebra servers.
407   Note path to server-side CQL-to-PQF config file, and to
408   SRW explain config section. 
409
410   The <directory> path is relative to the directory where zebra.init is placed
411   and is started up. The other pathes are relative to <directory>,
412   which in this case is the same.
413
414   see: http://www.indexdata.com/yaz/doc/server.vhosts.tkl
415
416    </para>
417
418    <para>
419 c)  Main "alvis" XSLT filter config file:
420   cat db/filter_alvis_conf.xml 
421
422   <?xml version="1.0" encoding="UTF8"?>
423   <schemaInfo>
424     <schema name="alvis" stylesheet="db/alvis2alvis.xsl" />
425     <schema name="index" identifier="http://indexdata.dk/zebra/xslt/1"
426             stylesheet="db/alvis2index.xsl" />
427     <schema name="dc" stylesheet="db/alvis2dc.xsl" />
428     <schema name="dc-short" stylesheet="db/alvis2dc_short.xsl" />
429     <schema name="snippet" snippet="25" stylesheet="db/alvis2snippet.xsl" />
430     <schema name="help" stylesheet="db/alvis2help.xsl" />
431     <split level="1"/>
432   </schemaInfo>
433
434   the pathes are relative to the directory where zebra.init is placed
435   and is started up.
436
437   The split level decides where the SAX parser shall split the
438   collections of records into individual records, which then are
439   loaded into DOM, and have the indexing XSLT stylesheet applied.
440
441   The indexing stylesheet is found by it's identifier.
442
443   All the other stylesheets are for presentation after search.
444
445 - in data/ a short sample of harvested carnivorous plants
446   ZEBRA_INDEX_DIRS=data/carnivor_20050118_2200_short-346.xml
447
448 - in root also one single data record - nice for testing the xslt
449   stylesheets,
450   
451   xsltproc db/alvis2index.xsl carni*.xml
452
453   and so on.
454
455 - in db/ a cql2pqf.txt yaz-client config file 
456   which is also used in the yaz-server CQL-to-PQF process
457
458    see: http://www.indexdata.com/yaz/doc/tools.tkl#tools.cql.map
459
460 - in db/ an indexing XSLT stylesheet. This is a PULL-type XSLT thing,
461   as it constructs the new XML structure by pulling data out of the
462   respective elements/attributes of the old structure.
463
464   Notice the special zebra namespace, and the special elements in this
465   namespace which indicate to the zebra indexer what to do.
466
467   <z:record id="67ht7" rank="675" type="update">
468   indicates that a new record with given id and static rank has to be updated. 
469
470   <z:index name="title" type="w">
471    encloses all the text/XML which shall be indexed in the index named
472    "title" and of index type "w" (see  file default.idx in your zebra
473    installation) 
474
475
476    </para>
477
478    <para>
479  Z39.50 searching:
480
481   search like this (using client-side CQL-to-PQF conversion):
482
483   yaz-client -q db/cql2pqf.txt localhost:9999
484   > format xml
485   > querytype cql2rpn
486   > f text=(plant and soil)
487   > s 1
488   > elements dc
489   > s 1
490   > elements index
491   > s 1
492   > elements alvis
493   > s 1
494   > elements snippet
495   > s 1
496
497
498   search like this (using server-side CQL-to-PQF conversion):
499   (the only difference is "querytype cql" instead of 
500    "querytype cql2rpn" and the call without specifying a local
501   conversion file)
502
503   yaz-client localhost:9999
504  > format xml
505   > querytype cql
506   > f text=(plant and soil)
507   > s 1
508   > elements dc
509   > s 1
510   > elements index
511   > s 1
512   > elements alvis
513   > s 1
514   > elements snippet
515   > s 1
516
517   NEW: static relevance ranking - see examples in alvis2index.xsl
518
519   > f text = /relevant (plant and soil)
520   > elem dc
521   > s 1
522
523   > f title = /relevant a
524   > elem dc
525   > s 1
526
527
528
529 SRW/U searching
530  Surf into http://localhost:9999
531  
532  firefox http://localhost:9999
533  
534  gives you an explain record. Unfortunately, the data found in the 
535  CQL-to-PQF text file must be added by hand-craft into the explain
536  section of the yazserver.xml file. Too bad, but this is all extreme
537  new alpha stuff, and a lot of work has yet to be done ..
538  
539  Searching via SRU: surf into the URL (lines broken here - concat on
540  URL line)
541  
542  - see number of hits:
543  http://localhost:9999/?version=1.1&operation=searchRetrieve
544                        &query=text=(plant%20and%20soil)
545  
546
547  - fetch record 5-7 in DC format
548  http://localhost:9999/?version=1.1&operation=searchRetrieve
549                        &query=text=(plant%20and%20soil)
550                        &startRecord=5&maximumRecords=2&recordSchema=dc
551  
552  
553  - even search using PQF queries using the extended verb "x-pquery",
554    which is special to YAZ/Zebra
555  
556  http://localhost:9999/?version=1.1&operation=searchRetrieve
557                        &x-pquery=@attr%201=text%20@and%20plant%20soil
558  
559  More info: read the fine manuals at http://www.loc.gov/z3950/agency/zing/srw/
560 278,280d299
561  Search via SRW:
562  read the fine manual at 
563  http://www.loc.gov/z3950/agency/zing/srw/
564
565  
566 and so on. The list of available indexes is found in db/cql2pqf.txt
567
568
569 7) How do you add to the index attributes of any other type than "w"?
570 I mean, in the context of making CQL queries. Let's say I want a date 
571 attribute in there, so that one could do date > 20050101 in CQL.
572
573 Currently for example 'date-modified' is of type 'w'.
574
575 The 2-seconds-of-though solution:
576
577      in alvis2index.sl:
578
579   <z:index name="date-modified" type="d">
580       <xsl:value-of 
581            select="acquisition/acquisitionData/modifiedDate"/>
582     </z:index>
583
584 But here's the catch...doesn't the use of the 'd' type require 
585 structure type 'date' (@attr 4=5) in PQF? But then...how does that
586 reflect in the CQL->RPN/PQF mapping - does it really work if I just
587 change the type of an element in alvis2index.sl? I would think not...?
588
589
590
591
592               Kimmo
593
594
595 Either do:
596
597    f @attr 4=5 @attr 1=date-modified 20050713
598
599 or do 
600
601
602 Either do:
603
604    f @attr 4=5 @attr 1=date-modified 20050713
605
606 or do 
607
608 querytype cql
609
610  f date-modified=20050713
611
612  f date-modified=20050713
613  
614  Search ERROR 121 4 1+0 RPN: @attrset Bib-1 @attr 5=100 @attr 6=1 @attr 3=3 @att
615 r 4=1 @attr 2=3 @attr "1=date-modified" 20050713
616
617
618
619  f date-modified eq 20050713
620
621 Search OK 23 3 1+0 RPN: @attrset Bib-1 @attr 5=100 @attr 6=1 @attr 3=3 @attr 4=5
622  @attr 2=3 @attr "1=date-modified" 20050713
623
624
625    </para>
626
627    <para>
628 E) EXTENDED SERVICE LIFE UPDATES
629
630 The extended services are not enabled by default in zebra - due to the
631 fact that they modify the system.
632
633 In order to allow anybody to update, use
634 perm.anonymous: rw
635 in zebra.cfg.
636
637 Or, even better, allow only updates for a particular admin user. For
638 user 'admin', you could use:
639 perm.admin: rw
640 passwd: passwordfile
641
642 And in passwordfile, specify users and passwords ..
643 admin:secret
644
645 We can now start a yaz-client admin session and create a database:
646
647 $ yaz-client localhost:9999 -u admin/secret
648 Authentication set to Open (admin/secret)
649 Connecting...OK.
650 Sent initrequest.
651 Connection accepted by v3 target.
652 ID     : 81
653 Name   : Zebra Information Server/GFS/YAZ
654 Version: Zebra 1.4.0/1.63/2.1.9
655 Options: search present delSet triggerResourceCtrl scan sort
656 extendedServices namedResultSets
657 Elapsed: 0.007046
658 Z> adm-create
659 Admin request
660 Got extended services response
661 Status: done
662 Elapsed: 0.045009
663 :
664 Now Default was created..  We can now insert an XML file (esdd0006.grs
665 from example/gils/records) and index it:
666
667 Z> update insert 1 esdd0006.grs
668 Got extended services response
669 Status: done
670 Elapsed: 0.438016
671
672 The 3rd parameter.. 1 here .. is the opaque record id from Ext update.
673 It a record ID that _we_ assign to the record in question. If we do not
674 assign one the usual rules for match apply (recordId: from zebra.cfg).
675
676 Actually, we should have a way to specify "no opaque record id" for
677 yaz-client's update command.. We'll fix that.
678
679 Elapsed: 0.438016
680 Z> f utah
681 Sent searchRequest.
682 Received SearchResponse.
683 Search was a success.
684 Number of hits: 1, setno 1
685 SearchResult-1: term=utah cnt=1
686 records returned: 0
687 Elapsed: 0.014179
688
689 Let's delete the beast:
690 Z> update delete 1
691 No last record (update ignored)
692 Z> update delete 1 esdd0006.grs
693 Got extended services response
694 Status: done
695 Elapsed: 0.072441
696 Z> f utah
697 Sent searchRequest.
698 Received SearchResponse.
699 Search was a success.
700 Number of hits: 0, setno 2
701 SearchResult-1: term=utah cnt=0
702 records returned: 0
703 Elapsed: 0.013610
704
705 If shadow register is enabled you must run the adm-commit command in
706 order write your changes..
707
708    </para>
709
710
711
712   </sect1>
713 -->
714
715  </chapter> 
716
717  <!-- Keep this comment at the end of the file
718  Local variables:
719  mode: sgml
720  sgml-omittag:t
721  sgml-shorttag:t
722  sgml-minimize-attributes:nil
723  sgml-always-quote-attributes:t
724  sgml-indent-step:1
725  sgml-indent-data:t
726  sgml-parent-document: "zebra.xml"
727  sgml-local-catalogs: nil
728  sgml-namecase-general:t
729  End:
730  -->