Documented lockPath.
[idzebra-moved-to-github.git] / doc / zebra.sgml
1 <!doctype linuxdoc system>
2
3 <!--
4   $Id: zebra.sgml,v 1.23 1996-03-26 15:59:46 adam Exp $
5 -->
6
7 <article>
8 <title>Zebra Server - Administrators's Guide and Reference
9 <author><htmlurl url="http://www.indexdata.dk/" name="Index Data">, <tt><htmlurl url="mailto:info@index.ping.dk" name="info@index.ping.dk"></>
10 <date>$Revision: 1.23 $
11 <abstract>
12 The Zebra information server combines a versatile fielded/free-text
13 search engine with a Z39.50-1995 frontend to provide a powerful and flexible
14 information management system. This document explains the procedure for
15 installing and configuring the system, and outlines the possibilities
16 for managing data and providing Z39.50
17 services with the software.
18 </abstract>
19
20 <toc>
21
22 <sect>Introduction
23
24 <sect1>Overview
25
26 <p>
27 The Zebra system is a fielded free-text indexing and retrieval engine with a
28 Z39.50 frontend. You can use any commercial or freeware Z39.50 client
29 to access data stored in Zebra.
30
31 The Zebra server is our first step towards the development of a fully
32 configurable, open information system. Eventually, it will be paired
33 off with a powerful Z39.50 client to support complex information
34 management tasks within almost any application domain. We're making
35 the server available now because it's no fun to be in the open
36 information retrieval business all by yourself. We want to allow
37 people with interesting data to make their things
38 available in interesting ways, without having to start out
39 by implementing yet another protocol stack from scratch.
40
41 This document is an introduction to the Zebra system. It will tell you
42 how to compile the software, and how to prepare your first database.
43 It also explains how the server can be configured to give you the
44 functionality that you need.
45
46 If you find the software interesting, you should join the support
47 mailing-list by sending Email to <tt/zebra-request@index.ping.dk/.
48
49 <sect1>Features
50
51 <p>
52 This is a listof some of the most important features of the
53 system.
54
55 <itemize>
56
57 <item>
58 Supports updating - records can be added and deleted without
59 rebuilding the index from scratch.
60 The update procedure is tolerant to crashes or hard interrupts
61 during register updating - registers can be reconstructed following a crash.
62 Registers can be safely updated even while users are accessing the server.
63
64 <item>
65 Supports large databases - files for indices, etc. can be
66 automatically partitioned over multiple disks.
67
68 <item>
69 Supports arbitrarily complex records - base input format is an
70 SGML-like syntax which allows nested (structured) data elements, as
71 well as variant forms of data.
72
73 <item>
74 Supports boolean queries as well as relevance-ranking (free-text)
75 searching. Right truncation and masking in terms are supported, as
76 well as full regular expressions.
77
78 <item>
79 Supports multiple concrete syntaxes
80 for record exchange (depending on the configuration): GRS-1, SUTRS,
81 ISO2709 (*MARC). Records can be mapped between record syntaxes and
82 schema on the fly.
83
84 <item>
85 Protocol support:
86
87 <itemize>
88
89 <item>
90 Protocol facilities: Init, Search, Retrieve, Browse.
91
92 <item>
93 Piggy-backed presents are honored in the search-request.
94
95 <item>
96 Named result sets are supported.
97
98 <item>
99 Easily configured to support different application profiles, with
100 tables for attribute sets, tag sets, and abstract syntaxes.
101 Additional tables control facilities such as element mappings to
102 different schema (eg., GILS-to-USMARC).
103
104 <item>
105 Complex composition specifications using Espec-1 are partially
106 supported (simple element requests only).
107
108 <item>
109 Element Set Names are defined using the Espec-1 capability of the
110 system, and are given in configuration files as simple element
111 requests (and possibly variant requests).
112
113 <item>
114 Some variant support (not fully implemented yet).
115
116 <item>
117 Using the YAZ toolkit for the protocol implementation, the
118 server can utilise a plug-in XTI/mOSI implementation (not included) to
119 provide SR services over an OSI stack, as well as Z39.50 over TCP/IP.
120
121 </itemize>
122
123 </itemize>
124
125 <sect1>Future Work
126
127 <p>
128 This is an alfa-release of the software, to allow you to look at
129 it - try it out, and assess whether it can be of use to you. We expect
130 this version to be followed by a succession of beta-releases until we
131 arrive at a stable first version.
132
133 These are some of the plans that we have for the software in the near
134 and far future, approximately ordered after their relative importance.
135 Items marked with an
136 asterisk will be implemented before the
137 last beta release.
138
139 <itemize>
140
141 <item>
142 *Allow the system to handle other input formats. Specifically
143 MARC records and general, structured ASCII records (such as mail/news
144 files) parameterized by regular expressions.
145
146 <item>
147 *Complete the support for variants. Finalize support for the WAIS
148 retrieval methodology.
149
150 <item>
151 *Finalize the data element <it/include/ facility to support multimedia
152 data elements in records.
153
154 <item>
155 *Port the system to Windows NT.
156
157 <item>
158 Add index and data compression to save disk space.
159
160 <item>
161 Add more sophisticated relevance ranking mechanisms. Add support for soundex
162 and stemming. Add relevance feedback support.
163
164 <item>
165 Add Explain support.
166
167 <item>
168 Add support for very large records by implementing segmentation and/or
169 variant pieces.
170
171 <item>
172 Support the Item Update extended service of the protocol.
173
174 <item>
175 The Zebra search engine supports approximate string matching in the
176 index. We'd like to find a way to support and control this from RPN.
177
178 <item>
179 We want to add a management system that allows you to
180 control your databases and configuration tables from a graphical
181 interface. We'll probably use Tcl/Tk to stay platform-independent.
182
183 </itemize>
184
185 Programmers thrive on user feedback. If you are interested in a facility that
186 you don't see mentioned here, or if there's something you think we
187 could do better, please drop us a mail. If you think it's all really
188 neat, you're welcome to drop us a line saying that, too. You'll find
189 contact info at the end of this file.
190
191 <sect>Compiling the software
192
193 <p>
194 Zebra uses the YAZ package to implement Z39.50, so you
195 have to compile YAZ before going further. Specifically, Zebra uses
196 the YAZ header files in <tt>yaz/include/..</tt> and its public library
197 <tt>yaz/lib/libyaz.a</tt>.
198
199 As with YAZ, an ANSI C compiler is required in order to compile the Zebra
200 server system &mdash; <tt/gcc/ works fine if your own system doesn't
201 provide an adequate compiler.
202
203 Unpack the Zebra software. You might put Zebra in the same directory level
204 as YAZ, for example if YAZ is placed in ..<tt>/src/yaz-xxx</tt>, then
205 Zebra is placed in ..<tt>/src/zebra-yyy</tt>.
206
207 Edit the top-level <tt>Makefile</tt> in the Zebra directory in which
208 you specify the location of YAZ by setting make variables.
209 The <tt>OSILIB</tt> should be empty if YAZ wasn't compiled with
210 MOSI support. Some systems, such as Solaris, have separate socket
211 libraries and for those systems you need to specify the
212 <tt>NETLIB</tt> variable.
213
214 When you are done editing the <tt>Makefile</tt> type:
215 <tscreen><verb>
216 $ make
217 </verb></tscreen>
218
219 If successful, two executables have been created in the sub-directory
220 <tt/index/.
221 <descrip>
222 <tag><tt>zebrasrv</tt></tag> The Z39.50 server and search engine.
223 <tag><tt>zebraidx</tt></tag> The administrative tool for the search index.
224 </descrip>
225
226 <sect>Quick Start
227
228 <p>
229 In this section, we will test the system by indexing a small set of sample
230 GILS records that are included with the software distribution. Go to the
231 <tt>test</tt> subdirectory of the distribution archive. There you will
232 find a configuration
233 file named <tt>zebra.cfg</tt> with the following contents:
234 <tscreen><verb>
235 # Where are the YAZ tables located.
236 profilePath: ../../yaz/tab ../tab
237
238 # Files that describe the attribute sets supported.
239 attset: bib1.att
240 attset: gils.att
241 </verb></tscreen>
242
243 Now, edit the file and set <tt>profilePath</tt> to the path of the
244 YAZ profile tables (sub directory <tt>tab</tt> of the YAZ distribution
245 archive).
246
247 The 48 test records are located in the sub directory <tt>records</tt>.
248 To index these, type:
249 <tscreen><verb>
250 $ ../index/zebraidx -t grs update records
251 </verb></tscreen>
252
253 In the command above the option <tt>-t</tt> specified the record
254 type &mdash; in this case <tt>grs</tt>. The word <tt>update</tt> followed
255 by a directory root updates all files below that directory node.
256
257 If your indexing command was successful, you are now ready to
258 fire up a server. To start a server on port 2100, type:
259 <tscreen><verb>
260 $ ../index/zebrasrv tcp:@:2100
261 </verb></tscreen>
262
263 The Zebra index that you have just created has a single database
264 named <tt/Default/. The database contains records structured according to
265 the GILS profile, and the server will
266 return records in either either USMARC, GRS-1, or SUTRS depending
267 on what your client asks
268 for.
269
270 To test the server, you can use any Z39.50 client (1992 or later). For
271 instance, you can use the demo client that comes with YAZ: Just cd to
272 the <tt/client/ subdirectory of the YAZ distribution and type:
273
274 <tscreen><verb>
275 $ client tcp:localhost:2100
276 </verb></tscreen>
277
278 When the client has connected, you can type:
279
280 <tscreen><verb>
281 Z> find surficial
282 Z> show 1
283 </verb></tscreen>
284
285 The default retrieval syntax for the client is USMARC. To try other
286 formats for the same record, try:
287
288 <tscreen><verb>
289 Z>format sutrs
290 Z>show 1
291 Z>format grs-1
292 Z>show 1
293 Z>elements B
294 Z>show 1
295 </verb></tscreen>
296
297 <it>NOTE: You may notice that more fields are returned when your
298 client requests SUTRS or GRS-1 records. When retrieving GILS records,
299 this is normal - not all of the GILS data elements have mappings in
300 the USMARC record format.</it>
301
302 If you've made it this far, there's a good chance that
303 you've got through the compilation OK.
304
305 <sect>Administrating Zebra<label id="administrating">
306
307 <p>
308 Unlike many simpler retrieval systems, Zebra supports safe, incremental
309 updates to an existing index.
310
311 Normally, when Zebra modifies the index it reads a number of records
312 that you specify.
313 Depending on your specifications and on the contents of each record
314 one the following events take place for each record:
315 <descrip>
316 <tag>Insert</tag> The record is indexed as if it never occurred
317 before. Either the Zebra system doesn't know how to identify the record or
318 Zebra can identify the record but didn't find it to be already indexed.
319 <tag>Modify</tag> The record has already been indexed. In this case
320 either the contents of the record or the location (file) of the record
321 indicates that it has been indexed before.
322 <tag>Delete</tag> The record is deleted from the index. As in the
323 update-case it must be able to identify the record.
324 </descrip>
325
326 Please note that in both the modify- and delete- case the Zebra
327 indexer must be able to generate a unique key that identifies the record in
328 question (more on this below).
329
330 To administrate the Zebra retrieval system, you run the
331 <tt>zebraidx</tt> program. This program supports a number of options
332 which are preceded by a minus, and a few commands (not preceded by
333 minus).
334
335 Both the Zebra administrative tool and the Z39.50 server share a
336 set of index files and a global configuration file. The
337 name of the configuration file defaults to <tt>zebra.cfg</tt>.
338 The configuration file includes specifications on how to index
339 various kinds of records and where the other configuration files
340 are located. <tt>zebrasrv</tt> and <tt>zebraidx</tt> <em>must</em>
341 be run in the directory where the configuration file lives unless you
342 indicate the location of the configuration file by option
343 <tt>-c</tt>.
344
345 <sect1>Record Types<label id="record-types">
346 <p>
347 Indexing is a per-record process, in which
348 either insert/modify/delete will occur. Before a record is indexed
349 search keys are extracted from whatever might be the layout the
350 original record (sgml,html,text, etc..). The Zebra system 
351 currently only supports SGML-like, structured records and unstructured text
352 records.
353 To specify a particular extraction process, use either the
354 command line option <tt>-t</tt> or specify a
355 <tt>recordType</tt> setting in the configuration file.
356
357 <sect1>The Zebra Configuration File<label id="configuration-file">
358 <p>
359 The Zebra configuration file, read by <tt>zebraidx</tt> and
360 <tt>zebrasrv</tt> defaults to <tt>zebra.cfg</tt> unless specified
361 by <tt>-c</tt> option.
362
363 You can edit the configuration file with a normal text editor.
364 Parameter names and values are seperated by colons in the file. Lines
365 starting with a hash sign (<tt/&num;/) are treated as comments.
366
367 If you manage different sets of records that share common
368 characteristics, you can organize the configuration settings for each
369 type into &dquot;groups&dquot;.
370 When <tt>zebraidx</tt> is run and you wish to address a given group
371 you specify the group name with the <tt>-g</tt> option. In this case
372 settings that have the group name as their prefix will be used
373 by <tt>zebraidx</tt>. If no <tt/-g/ option is specified, the settings
374 with no prefix are used.
375
376 In the configuration file, the group name is placed before the option
377 name
378 itself, separated by a dot (.). For instance, to set the record type
379 for group <tt/public/ to <tt/grs/ (the common format for structured
380 records) you would write:
381
382 <tscreen><verb>
383 public.recordType: grs
384 </verb></tscreen>
385
386 To set the default value of the record type to <tt/text/ write:
387
388 <tscreen><verb>
389 recordType: text
390 </verb></tscreen>
391
392 The available configuration settings are summarized below. They will be
393 explained further in the following sections.
394
395 <descrip>
396 <tag><it>group</it>.recordType&lsqb;<it>.name</it>&rsqb;</tag>
397  Specifies how records with the file extension <it>name</it> should
398  be handled by the indexer. This option may also be specified
399  as a command line option (<tt>-t</tt>). Note that if you do not
400  specify a <it/name/, the setting applies to all files.
401 <tag><it>group</it>.recordId</tag>
402  Specifies how the records are to be identified when updated. See
403 section <ref id="locating-records" name="Locating Records">.
404 <tag><it>group</it>.database</tag>
405  Specifies the Z39.50 database name.
406 <tag><it>group</it>.storeKeys</tag>
407  Specifies whether key information should be saved for a given
408  group of records. If you plan to update/delete this type of
409  records later this should be specified as 1; otherwise it
410  should be 0 (default), to save register space. See section
411 <ref id="file-ids" name="Indexing With File Record IDs">.
412 <tag><it>group</it>.storeData</tag>
413  Specifies whether the records should be stored internally
414  in the Zebra system files. If you want to maintain the raw records yourself,
415  this option should be false (0). If you want Zebra to take care of the records
416  for you, it should be true(1).
417 <tag>register</tag> 
418  Specifies the location of the various register files that Zebra uses
419  to represent your databases. See section
420 <ref id="register-location" name="Register Location">.
421 <tag>shadow</tag>
422  Enables the <it/safe update/ facility of Zebra, and tells the system
423  where to place the required, temporary files. See section
424 <ref id="shadow-registers" name="Safe Updating - Using Shadow Registers">.
425 <tag>lockPath</tag>
426  Directory in which various lock files are stored.
427 <tag>tempSetPath</tag>
428  Specifies the directory that the server uses for temporary result sets.
429  If not specified <tt>/tmp</tt> will be used.
430 <tag>profilePath</tag>
431  Specifies the location of profile specification files.
432 <tag>attset</tag> 
433  Specifies the filename(s) of attribute set files for use in
434  searching. At least the Bib-1 set should be loaded (<tt/bib1.att/).
435  The <tt/profilePath/ setting is used to look for the specified files.
436  See section <ref id="attset-files" name="The Attribute Set Files">
437 </descrip>
438
439 <sect1>Locating Records<label id="locating-records">
440 <p>
441 The default behaviour of the Zebra system is to reference the
442 records from their original location, i.e. where they were found when you
443 ran <tt/zebraidx/. That is, when a client wishes to retrieve a record
444 following a search operation, the files are accessed from the place
445 where you originally put them - if you remove the files (without
446 running <tt/zebraidx/ again, the client will receive a diagnostic
447 message.
448
449 If your input files are not permanent - for example if you retrieve
450 your records from an outside source, or if they were temporarily
451 mounted on a CD-ROM drive,
452 you may want Zebra to make an internal copy of them. To do this,
453 you specify 1 (true) in the <tt>storeData</tt> setting. When
454 the Z39.50 server retrieves the records they will be read from the
455 internal file structures of the system.
456
457 <sect1>Indexing with no Record IDs (Simple Indexing)
458
459 <p>
460 If you have a set of records that is not expected to change over time
461 you may can build your database without record IDs.
462 This indexing method uses less space than the other methods and
463 is simple to use. 
464
465 To use this method, you simply don't provide the <tt>recordId</tt> entry
466 for the group of files that you index. To add a set of records you use
467 <tt>zebraidx</tt> with the <tt>update</tt> command. The
468 <tt>update</tt> command will always add all of the records that it
469 encounters to the index - whether they have already been indexed or
470 not. If the set of indexed files change, you should delete all of the
471 index files, and build a new index from scratch.
472
473 Consider a system in which you have a group of text files called
474 <tt>simple</tt>. That group of records should belong to a Z39.50 database
475 called <tt>textbase</tt>. The following <tt/zebra.cfg/ file will suffice:
476
477 <tscreen><verb>
478 profilePath: /usr/local/yaz
479 attset: bib1.att
480 simple.recordType: text
481 simple.database: textbase
482 </verb></tscreen>
483
484 Since the existing records in an index can not be addressed by their
485 IDs, it is impossible to delete or modify records when using this method.
486
487 <sect1>Indexing with File Record IDs<label id="file-ids">
488
489 <p>
490 If you have a set of files that regularly change over time: Old files
491 are deleted, new ones are added, or existing files are modified, you
492 can benefit from using the <it/file ID/ indexing methodology. Examples
493 of this type of database might include an index of WWW resources, or a
494 USENET news spool area. Briefly speaking, the file key methodology
495 uses the directory paths of the individual records as a unique
496 identifier for each record. To perform indexing of a directory with
497 file keys, again, you specify the top-level directory after the
498 <tt>update</tt> command. The command will recursively traverse the
499 directories and compare each one with whatever have been indexed before in
500 that same directory. If a file is new (not in the previous version of
501 the directory) it is inserted into the registers; if a file was
502 already indexed and it has been modified since the last update,
503 the index is also modified; if a file has been removed since the last
504 visit, it is deleted from the index.
505
506 The resulting system is easy to administrate. To delete a record you
507 simply have to delete the corresponding file (say, with the <tt/rm/
508 command). And to add records you create new files (or directories with
509 files). For your changes to take effect in the register you must run
510 <tt>zebraidx update</tt> with the same directory root again. This mode
511 of operation requires more disk space than simpler indexing methods,
512 but it makes it easier for you to keep the index in sync with a
513 frequently changing set of data. If you combine this system with the
514 <it/safe update/ facility (see below), you never have to take your
515 server offline for maintenance or register updating purposes.
516
517 To enable indexing with pathname IDs, you must specify <tt>file</tt> as
518 the value of <tt>recordId</tt> in the configuration file. In addition,
519 you should set <tt>storeKeys</tt> to <tt>1</tt>, since the Zebra
520 indexer must save additional information about the contents of each record
521 in order to modify the indices correctly at a later time.
522
523 For example, to update records of group <tt>esdd</tt> located below
524 <tt>/data1/records/</tt> you should type:
525 <tscreen><verb>
526 $ zebraidx -g esdd update /data1/records
527 </verb></tscreen>
528
529 The corresponding configuration file includes:
530 <tscreen><verb>
531 esdd.recordId: file
532 esdd.recordType: grs
533 esdd.storeKeys: 1
534 </verb></tscreen>
535
536 <em>Important note: You cannot start out with a group of records with simple
537 indexing (no record IDs as in the previous section) and then later
538 enable file record Ids. Zebra must know from the first time that you
539 index the group that
540 the files should be indexed with file record IDs.
541 </em>
542
543 You cannot explicitly delete records when using this method (using the
544 <bf/delete/ command to <tt/zebraidx/. Instead
545 you have to delete the files from the file system (or move them to a
546 different location)
547 and then run <tt>zebraidx</tt> with the <bf/update/ command.
548
549 <sect1>Indexing with General Record IDs
550 <p>
551 When using this method you construct an (almost) arbritrary, internal
552 record key based on the contents of the record itself and other system
553 information. If you have a group of records that explicitly associates
554 an ID with each record, this method is convenient. For example, the
555 record format may contain a title or a ID-number - unique within the group.
556 In either case you specify the Z39.50 attribute set and use-attribute
557 location in which this information is stored, and the system looks at
558 that field to determine the identity of the record.
559
560 As before, the record ID is defined by the <tt>recordId</tt> setting
561 in the configuration file. The value of the record ID specification
562 consists of one or more tokens separated by whitespace. The resulting
563 ID is
564 represented in the index by concatenating the tokens and separating them by
565 ASCII value (1).
566
567 There are three kinds of tokens:
568 <descrip>
569 <tag>Internal record info</tag> The token refers to a key that is
570 extracted from the record. The syntax of this token is
571  <tt/(/ <em/set/ <tt/,/ <em/use/ <tt/)/, where <em/set/ is the
572 attribute set ordinal number and <em/use/ is the use value of the attribute.
573 <tag>System variable</tag> The system variables are preceded by
574 <verb>$</verb> and immediately followed by the system variable name, which
575 may one of
576  <descrip>
577  <tag>group</tag> Group name.
578  <tag>database</tag> Current database specified.
579  <tag>type</tag> Record type.
580  </descrip>
581 <tag>Constant string</tag> A string used as part of the ID &mdash; surrounded
582  by single- or double quotes.
583 </descrip>
584
585 For instance, the sample GILS records that come with the Zebra
586 distribution contain a
587 unique ID
588 in the Control-Identifier field. This field is mapped to the Bib-1
589 use attribute 1007. To use this field as a record id, specify
590 <tt>(1,1007)</tt> as the value of the <tt>recordId</tt> in the
591 configuration file. If you have other record types that uses
592 the same field for a different purpose, you might add the record type (or group or database name)
593 to the record id of the gils records as well, to prevent matches
594 with other types of records. In this case the recordId might be
595 set like this:
596 <tscreen><verb>
597 gils.recordId: $type (1,1007)
598 </verb></tscreen>
599
600 (see section <ref id="data-model" name="Configuring Your Data Model">
601 for details of how the mapping between elements of your records and
602 searchable attributes is established).
603
604 As for the file record ID case described in the previous section,
605 updating your system is simply a matter of running <tt>zebraidx</tt>
606 with the <tt>update</tt> command. However, the update with general
607 keys is considerably slower than with file record IDs, since all files
608 visited must be (re)read to discover their IDs. 
609
610 As you might expect, when using the general record IDs
611 method, you can only add or modify existing records with the <tt>update</tt>
612 command. If you wish to delete records, you must use the,
613 <tt>delete</tt> command, with a directory as a parameter.
614 This will remove all records that match the files below that root
615 directory.
616
617 <sect1>Register Location<label id="register-location">
618
619 <p>
620 Normally, the index files that form dictionaries, inverted
621 files, record info, etc., are stored in the directory where you run
622 <tt>zebraidx</tt>. If you wish to store these, possibly large, files
623 somewhere else, you must add the <tt>register</tt> entry to the
624 <tt/zebra.cfg/ file. Furthermore, the Zebra system allows its file
625 structures to
626 span multiple file systems, which is useful for managing very large
627 databases. 
628
629 The value of the <tt>register</tt> setting is a sequence of tokens.
630 Each token takes the form:
631 <tscreen>
632 <em>dir</em><tt>:</tt><em>size</em>. 
633 </tscreen>
634 The <em>dir</em> specifies a directory in which index files will be
635 stored and the <em>size</em> specifies the maximum size of all
636 files in that directory. The Zebra indexer system fills each directory
637 in the order specified and use the next specified directories as needed.
638 The <em>size</em> is an integer followed by a qualifier
639 code, <tt>M</tt> for megabytes, <tt>k</tt> for kilobytes.
640
641 For instance, if you have allocated two disks for your register, and
642 the first disk is mounted
643 on <tt>/d1</tt> and has 200 Mb of free space and the
644 second, mounted on <tt>/d2</tt> has 300 Mb, you could
645 put this entry in your configuration file:
646 <tscreen><verb>
647 register: /d1:200M /d2:300M
648 </verb></tscreen>
649
650 Note that Zebra does not verify that the amount of space specified is
651 actually available on the directory (file system) specified - it is
652 your responsibility to ensure that enough space is available, and that
653 other applications do not attempt to use the free space. In a large production system,
654 it is recommended that you allocate one or more filesystem exclusively
655 to the Zebra register files.
656
657 <sect1>Safe Updating - Using Shadow Registers<label id="shadow-registers">
658
659 <sect2>Description
660
661 <p>
662 The Zebra server supports <it/updating/ of the index structures. That is,
663 you can add, modify, or remove records from databases managed by Zebra
664 without rebuilding the entire index. Since this process involves
665 modifying structured files with various references between blocks of
666 data in the files, the update process is inherently sensitive to
667 system crashes, or to process interruptions: Anything but a
668 successfully completed update process will leave the register files in
669 an unknown state, and you will essentially have no recourse but to
670 re-index everything, or to restore the register files from a backup
671 medium. Further, while the update process is active, users cannot be
672 allowed to access the system, as the contents of the register files
673 may change unpredictably.
674
675 You can solve these problems by enabling the shadow register system in
676 Zebra. During the updating procedure, <tt/zebraidx/ will temporarily
677 write changes to the involved files in a set of &dquot;shadow
678 files&dquot;, without modifying the files that are accessed by the
679 active server processes. If the update procedure is interrupted by a
680 system crash or a signal, you simply repeat the procedure - the
681 register files have not been changed or damaged, and the partially
682 written shadow files are automatically deleted before the new updating
683 procedure commences.
684
685 At the end of the updating procedure (or in a separate operation, if
686 you so desire), the system enters a &dquot;commit mode&dquot;. First,
687 any active server processes are forced to access those blocks that
688 have been changed from the shadow files rather than from the main
689 register files; the unmodified blocks are still accessed at their
690 normal location (the shadow files are not a complete copy of the
691 register files - they only contain those parts that have actually been
692 modified). If the commit process is interrupted at any point during the
693 commit process, the server processes will continue to access the
694 shadow files until you can repeat the commit procedure and complete
695 the writing of data to the main register files. You can perform
696 multiple update operations to the registers before you commit the
697 changes to the system files, or you can execute the commit operation
698 at the end of each update operation. When the commit phase has
699 completed successfully, any running server processes are instructed to
700 switch their operations to the new, operational register, and the
701 temporary shadow files are deleted.
702
703 <sect2>How to Use Shadow Register Files
704
705 <p>
706 The first step is to allocate space on your system for the shadow
707 files. You do this by adding a <tt/shadow/ entry to the <tt/zebra.cfg/
708 file. The syntax of the <tt/shadow/ entry is exactly the same as for
709 the <tt/register/ entry (see section <ref name="Register Location"
710 id="register-location">). The location of the shadow area should be
711 <it/different/ from the location of the main register area (if you
712 have specified one - remember that if you provide no <tt/register/
713 setting, the default register area is the
714 working directory of the server and indexing processes).
715
716 The following excerpt from a <tt/zebra.cfg/ file shows one example of
717 a setup that configures both the main register location and the shadow
718 file area. Note that two directories or partitions have been set aside
719 for the shadow file area. You can specify any number of directories
720 for each of the file areas, but remember that there should be no
721 overlaps between the directories used for the main registers and the
722 shadow files, respectively.
723
724 <tscreen><verb>
725 register: /d1:500M
726
727 shadow: /scratch1:100M /scratch2:200M
728 </verb></tscreen>
729
730 When shadow files are enabled, an extra command is available at the
731 <tt/zebraidx/ command line. In order to make changes to the system
732 take effect for the users, you'll have to submit a
733 &dquot;commit&dquot; command after a (sequence of) update
734 operation(s). You can ask the indexer to commit the changes
735 immediately after the update operation:
736
737 <tscreen><verb>
738 $ zebraidx update /d1/records update /d2/more-records commit
739 </verb></tscreen>
740
741 Or you can execute multiple updates before committing the changes:
742
743 <tscreen><verb>
744 $ zebraidx -g books update /d1/records update /d2/more-records
745 $ zebraidx -g fun update /d3/fun-records
746 $ zebraidx commit
747 </verb></tscreen>
748
749 If one of the update operations above had been interrupted, the commit
750 operation on the last line would fail: <tt/zebraidx/ will not let you
751 commit changes that would destroy the running register. You'll have to
752 rerun all of the update operations since your last commit operation,
753 before you can commit the new changes.
754
755 Similarly, if the commit operation fails, <tt/zebraidx/ will not let
756 you start a new update operation before you have successfully repeated
757 the commit operation. The server processes will keep accessing the
758 shadow files rather than the (possibly damaged) blocks of the main
759 register files until the commit operation has successfully completed.
760
761 You should be aware that update operations may take slightly longer
762 when the shadow register system is enabled, since more file access
763 operations are involved. Further, while the disk space required for
764 the shadow register data is modest for a small update operation, you
765 may prefer to disable the system if you are adding a very large number
766 of records to an already very large database (we use the terms
767 <it/large/ and <it/modest/ very loosely here, since every
768 application will have a different perception of size). To update the system
769 without the use of the the shadow files, simply run <tt/zebraidx/ with
770 the <tt/-n/ option (note that you do not have to execute the
771 <bf/commit/ command of <tt/zebraidx/ when you temporarily disable the
772 use of the shadow registers in this fashion. Note also that, just as
773 when the shadow registers are not enabled, server processes will be
774 barred from accessing the main register while the update procedure
775 takes place.
776
777 <sect>Running the Maintenance Interface (zebraidx)
778
779 <p>
780 The following is a complete reference to the command line interface to
781 the <tt/zebraidx/ application.
782
783 <bf/Syntax/
784 <tscreen><verb>
785 $ zebraidx &lsqb;options&rsqb; command &lsqb;directory&rsqb; ...
786 </verb></tscreen>
787 <bf/Options/
788 <descrip>
789 <tag>-t <it/type/</tag>Update all files as <it/type/. Currently, the
790 types supported are <tt/text/ and <tt/grs/<it/.filter/. If no
791 <it/filter/ is provided for the GRS (General Record Structure) type,
792 the canonical input format is assumed (see section <ref
793 id="local-representation" name="Local Representation">). Generally, it
794 is probably advisable to specify the record types in the
795 <tt/zebra.cfg/ file (see section <ref id="record-types" name="Record Types">).
796
797 <tag>-c <it/config-file/</tag>Read the configuration file
798 <it/config-file/ instead of <tt/zebra.cfg/.
799
800 <tag>-g <it/group/</tag>Update the files according to the group
801 settings for <it/group/ (see section <ref id="configuration-file"
802 name="The Zebra Configuration File">).
803
804 <tag>-d <it/database/</tag>The records located should be associated
805 with the database name <it/database/ for access through the Z39.50
806 server.
807
808 <tag>-d <it/mbytes/</tag>Use <it/mbytes/ of megabytes before flushing
809 keys to background storage. This setting affects performance when
810 updating large databases.
811
812 <tag>-n</tag>Disable the use of shadow registers for this operation
813 (see section <ref id="shadow-registers" name="Robust Updating - Using
814 Shadow Registers">).
815
816 <tag>-v <it/level/</tag>Set the log level to <it/level/. <it/level/
817 should be one of <tt/none/, <tt/debug/, and <tt/all/.
818
819 </descrip>
820
821 <bf/Commands/
822 <descrip>
823 <tag>Update <it/directory/</tag>Update the register with the files
824 contained in <it/directory/. If no directory is provided, a list of
825 files is read from <tt/stdin/. See section <ref
826 id="administrating" name="Administrating Zebra">.
827
828 <tag>Delete <it/directory/</tag>Remove the records corresponding to
829 the files found under <it/directory/ from the register.
830
831 <tag/Commit/Write the changes resulting from the last <bf/update/
832 commands to the register. This command is only available if the use of
833 shadow register files is enabled (see section <ref
834 id="shadow-registers" name="Robust Updating - Using Shadow
835 Registers">).
836
837 </descrip>
838
839 <sect>Running the Z39.50 Server (zebrasrv)
840
841 <p>
842 <bf/Syntax/
843 <tscreen><verb>
844 zebrasrv &lsqb;options&rsqb; &lsqb;listener-address ...&rsqb;
845 </verb></tscreen>
846
847 <bf/Options/
848 <descrip>
849 <tag>-a <it/APDU file/</tag> Specify a file for dumping PDUs (for diagnostic purposes).
850 The special name &dquot;-&dquot; sends output to <tt/stderr/.
851
852 <tag>-c <it/config-file/</tag> Read configuration information from <it/config-file/. The default configuration is <tt>./zebra.cfg</tt>.
853
854 <tag/-S/Don't fork on connection requests. This can be useful for
855 symbolic-level debugging. The server can only accept a single
856 connection in this mode.
857
858 <tag/-s/Use the SR protocol.
859
860 <tag/-z/Use the Z39.50 protocol (default). These two options complement
861 eachother. You can use both multiple times on the same command
862 line, between listener-specifications (see below). This way, you
863 can set up the server to listen for connections in both protocols
864 concurrently, on different local ports.
865
866 <tag>-l <it/logfile/</tag>Specify an output file for the diagnostic
867 messages. The default is to write this information to <tt/stderr/.
868
869 <tag>-v <it/log-level/</tag>The log level. Use a comma-separated list of members of the set
870 {fatal,debug,warn,log,all,none}.
871
872 <tag>-u <it/username/</tag>Set user ID. Sets the real UID of the server process to that of the
873 given <it/username/. It's useful if you aren't comfortable with having the
874 server run as root, but you need to start it as such to bind a
875 privileged port.
876
877 <tag>-w <it/working-directory/</tag>Change working directory.
878
879 <tag/-i/Run under the Internet superserver, <tt/inetd/.
880 </descrip>
881
882 A <it/listener-address/ consists of a transport mode followed by a
883 colon (:) followed by a listener address. The transport mode is
884 either <tt/osi/ or <tt/tcp/.
885
886 For TCP, an address has the form
887
888 <tscreen><verb>
889 hostname | IP-number &lsqb;: portnumber&rsqb;
890 </verb></tscreen>
891
892 The port number defaults to 210 (standard Z39.50 port).
893
894 For OSI (only available if the server is compiled with XTI/mOSI
895 support enabled), the address form is
896
897 <tscreen><verb>
898 &lsqb;t-selector /&rsqb; hostname | IP-number &lsqb;: portnumber&rsqb;
899 </verb></tscreen>
900
901 The transport selector is given as a string of hex digits (with an even
902 number of digits). The default port number is 102 (RFC1006 port).
903
904 Examples
905
906 <tscreen>
907 <verb>
908 tcp:dranet.dra.com
909
910 osi:0402/dbserver.osiworld.com:3000
911 </verb>
912 </tscreen>
913
914 In both cases, the special hostname &dquot;@&dquot; is mapped to
915 the address INADDR_ANY, which causes the server to listen on any local
916 interface. To start the server listening on the registered ports for
917 Z39.50 and SR over OSI/RFC1006, and to drop root privileges once the
918 ports are bound, execute the server like this (from a root shell):
919
920 <tscreen><verb>
921 zebrasrv -u daemon tcp:@ -s osi:@
922 </verb></tscreen>
923
924 You can replace <tt/daemon/ with another user, eg. your own account, or
925 a dedicated IR server account.
926
927 The default behavior for <tt/zebrasrv/ is to establish a single TCP/IP
928 listener, for the Z39.50 protocol, on port 9999.
929
930 <sect>The Record Model
931
932 <p>
933 The Zebra system is designed to support a wide range of data management
934 applications. The system can be configured to handle virtually any
935 kind of structured data. Each record in the system is associated with
936 a <it/record schema/ which lends context to the data elements of the
937 record. Any number of record schema can coexist in the system.
938 Although it may be wise to use only a single schema within
939 one database, the system poses no such restrictions.
940
941 Records pass through three different states during processing in the
942 system.
943
944 <itemize>
945 <item>When records are accessed by the system, they are represented
946 in their local, or native format. This might be SGML or HTML files,
947 News or Mail archives, MARC records. If the system doesn't already
948 know how to read the type of data you need to store, you can set up an
949 input filter by preparing conversion rules based on regular
950 expressions and a flexible scripting language (Tcl). The input filter
951 produces as output an internal representation:
952
953 <item>When records are processed by the system, they are represented
954 in a tree-structure, constructed by tagged data elements hanging off a
955 root node. The tagged elements may contain data or yet more tagged
956 elements in a recursive structure. The system performs various
957 actions on this tree structure (indexing, element selection, schema
958 mapping, etc.),
959
960 <item>Before transmitting records to the client, they are first
961 converted from the internal structure to a form suitable for exchange
962 over the network - according to the Z39.50 standard.
963 </itemize>
964
965 <sect1>Local Representation<label id="local-representation">
966
967 <p>
968 As mentioned earlier, Zebra places few restrictions on the type of
969 data that you can index and manage. Generally, whatever the form of
970 the data, it is parsed by an input filter specific to that format, and
971 turned into an internal structure that Zebra knows how to handle. This
972 process takes place whenever the record is accessed - for indexing and
973 retrieval.
974
975 <sect2>Canonical Input Format
976
977 <p>
978 Although input data can take any form, it is sometimes useful to
979 describe the record processing capabilities of the system in terms of
980 a single, canonical input format that gives access to the full
981 spectrum of structure and flexibility in the system. In Zebra, this
982 canonical format is an &dquot;SGML-like&dquot; syntax.
983
984 Consider a record describing an information resource (such a record is
985 sometimes known as a <it/locator record/). It might contain a field
986 describing the distributor of the information resource, which might in
987 turn be partitioned into various fields providing details about the
988 distributor, like this:
989
990 <tscreen><verb>
991 <Distributor>
992     <Name> USGS/WRD &etago;Name>
993     <Organization> USGS/WRD &etago;Organization>
994     <Street-Address>
995         U.S. GEOLOGICAL SURVEY, 505 MARQUETTE, NW
996     &etago;Street-Address>
997     <City> ALBUQUERQUE &etago;City>
998     <State> NM &etago;State>
999     <Zip-Code> 87102 &etago;Zip-Code>
1000     <Country> USA &etago;Country>
1001     <Telephone> (505) 766-5560 &etago;Telephone>
1002 &etago;Distributor>
1003 </verb></tscreen>
1004
1005 <it>NOTE: The indentation used above is used to illustrate how Zebra
1006 interprets the markup. The indentation, in itself, has no
1007 significance to the parser for the canonical input format, which
1008 discards superfluous whitespace.</it>
1009
1010 The keywords surrounded by &lt;...&gt; are <it/tags/, while the
1011 sections of text in between are the <it/data elements/. A data element
1012 is characterized by its location in the tree that is made up by the
1013 nested elements. Each element is terminated by a closing tag -
1014 beginning with &etago;, and containing the same symbolic tag-name as
1015 the corresponding opening tag. The general closing tag - &etago;&gt; -
1016 terminates the element started by the last opening tag. The
1017 structuring of elements is significant. The element <bf/Telephone/,
1018 for instance, may be indexed and presented to the client differently,
1019 depending on whether it appears inside the <bf/Distributor/ element,
1020 or some other, structured data element such a <bf/Supplier/ element.
1021
1022 <sect3>Record Root
1023
1024 <p>
1025 The first tag in a record describes the root node of the tree that
1026 makes up the total record. In the canonical input format, the root tag
1027 should contain the name of the schema that lends context to the
1028 elements of the record (see section <ref id="internal-representation"
1029 name="Internal Representation">). The following is a GILS record that
1030 contains only a single element (strictly speaking, that makes it an
1031 illegal GILS record, since the GILS profile includes several mandatory
1032 elements - Zebra does not validate the contents of a record against
1033 the Z39.50 profile, however - it merely attempts to match up elements
1034 of a local representation with the given schema):
1035
1036 <tscreen><verb>
1037 <gils>
1038     <title>Zen and the Art of Motorcycle Maintenance&etago;title>
1039 &etago;gils>
1040 </verb></tscreen>
1041
1042 <sect3>Variants
1043
1044 <p>
1045 Zebra allows you to provide individual data elements in a number of
1046 <it/variant forms/. Examples of variant forms are textual data
1047 elements which might appear in different languages, and images which
1048 may appear in different formats or layouts. The variant system in
1049 Zebra is
1050 essentially a representation of the variant mechanism of
1051 Z39.50-1995.
1052
1053 The following is an example of a title element which occurs in two
1054 different languages.
1055
1056 <tscreen><verb>
1057 <title>
1058   <var lang lang "eng">
1059     Zen and the Art of Motorcycle Maintenance&etago;>
1060   <var lang lang "dan">
1061     Zen og Kunsten at Vedligeholde en Motorcykel&etago;>
1062 &etago;title>
1063 </verb></tscreen>
1064
1065 The syntax of the <it/variant element/ is <tt>&lt;<bf/var/ <it/class
1066 type value/&gt;</tt>. The available values for the <it/class/ and
1067 <it/type/ fields are given by the variant set that is associated with the
1068 current schema (see section <ref id="variant-set" name="Variant Set
1069 File">).
1070
1071 Variant elements are terminated by the general end-tag &etago;>, by
1072 the variant end-tag &etago;var>, by the appearance of another variant
1073 tag with the same <it/class/ and <it/value/ settings, or by the
1074 appearance of another, normal tag. In other words, the end-tags for
1075 the variants used in the example above could have been saved.
1076
1077 Variant elements can be nested. The element
1078
1079 <tscreen><verb>
1080 <title>
1081   <var lang lang "eng"><var body iana "text/plain">
1082     Zen and the Art of Motorcycle Maintenance
1083 &etago;title>
1084 </verb></tscreen>
1085
1086 Associates two variant components to the variant list for the title
1087 element.
1088
1089 Given the nesting rules described above, we could write
1090
1091 <tscreen><verb>
1092 <title>
1093   <var body iana "text/plain>
1094     <var lang lang "eng">
1095       Zen and the Art of Motorcycle Maintenance
1096     <var lang lang "dan">
1097       Zen og Kunsten at Vedligeholde en Motorcykel
1098 &etago;title>
1099 </verb></tscreen>
1100
1101 The title element above comes in two variants. Both have the IANA body
1102 type &dquot;text/plain&dquot;, but one is in English, and the other in
1103 Danish. The client, using the element selection mechanism of Z39.50,
1104 can retrieve information about the available variant forms of data
1105 elements, or it can select specific variants based on the requirements
1106 of the end-user.
1107
1108 <sect2>Input Filters
1109
1110 <p>
1111 In order to handle general input formats, Zebra allows the
1112 operator to define filters which read individual records in their native format
1113 and produce an internal representation that the system can
1114 work with.
1115
1116 Input filters are ASCII files, generally with the suffix <tt/.flt/.
1117 The system looks for the files in the directories given in the
1118 <bf/profilePath/ setting in the <tt/zebra.cfg/ file.
1119
1120 Generally, an input filter consists of a sequence of rules, where each
1121 rule consists of a sequence of expressions, followed by an action. The
1122 expressions are evaluated against the contents of the input record,
1123 and the actions normally contribute to the generation of an internal
1124 representation of the record.
1125
1126 An expression can be either of the following:
1127
1128 <descrip>
1129 <tag/INIT/The action associated with this expression is evaluated
1130 exactly once in the lifetime of the application, before any records
1131 are read. It can be used in conjunction with an action that
1132 initializes tables or other resources that are used in the processing
1133 of input records.
1134
1135 <tag/BEGIN/Matches the beginning of the record. It can be used to
1136 initialize variables, etc. Typically, the <bf/BEGIN/ rule is also used
1137 to establish the root node of the record.
1138
1139 <tag/END/Matches the end of the record - when all of the contents
1140 of the record has been processed.
1141
1142 <tag>/pattern/</tag>Matches a string of characters from the input
1143 record.
1144
1145 <tag/BODY/This keyword may only be used between two patterns. It
1146 matches everything between (not including) those patterns.
1147
1148 <tag/FINISH/THe expression asssociated with this pattern is evaluated
1149 once, before the application terminates. It can be used to release
1150 system resources - typically ones allocated in the <bf/INIT/ step.
1151
1152 </descrip>
1153
1154 An action is surrounded by curly braces ({...}), and consists of a
1155 sequence of statements. Statements may be separated by newlines or
1156 semicolons (;). Within actions, the strings that matched the
1157 expressions immediately preceding the action can be referred to as
1158 &dollar;0, &dollar;1, &dollar;2, etc.
1159
1160 The available statements are:
1161
1162 <descrip>
1163
1164 <tag>begin <it/type &lsqb;parameter ... &rsqb;/</tag>Begin a new
1165 data element. The type is one of the following:
1166 <descrip>
1167 <tag/record/Begin a new record. The followingparameter should be the
1168 name of the schema that describes the structure of the record, eg.
1169 <tt/gils/ or <tt/wais/ (see below). The <tt/begin record/ call should
1170 precede
1171 any other use of the <bf/begin/ statement.
1172
1173 <tag/element/Begin a new tagged element. The parameter is the
1174 name of the tag. If the tag is not matched anywhere in the tagsets
1175 referenced by the current schema, it is treated as a local string
1176 tag.
1177
1178 <tag/variant/Begin a new node in a variant tree. The parameters are
1179 <it/class type value/.
1180
1181 </descrip>
1182
1183 <tag/data/Create a data element. The concatenated arguments make
1184 up the value of the data element. The option <tt/-text/ signals that
1185 the layout (whitespace) of the data should be retained for
1186 transmission. The option <tt/-element/ <it/tag/ wraps the data up in
1187 the <it/tag/. The use of the <tt/-element/ option is equivalent to
1188 preceding the command with a <bf/begin element/ command, and following
1189 it with the <bf/end/ command.
1190
1191 <tag>end <it/&lsqb;type&rsqb;/</tag>Close a tagged element. If no parameter is given,
1192 the last element on the stack is terminated. The first parameter, if
1193 any, is a type name, similar to the <bf/begin/ statement. For the
1194 <bf/element/ type, a tag name can be provided to terminate a specific tag.
1195
1196 </descrip>
1197
1198 The following input filter reads a Usenet news file, producing a
1199 record in the WAIS schema. Note that the body of a news posting is
1200 separated from the list of headers by a blank line (or rather a
1201 sequence of two newline characters.
1202
1203 <tscreen><verb>
1204 BEGIN                { begin record wais }
1205
1206 /^From:/ BODY /$/    { data -element name $1 }
1207 /^Subject:/ BODY /$/ { data -element title $1 }
1208 /^Date:/ BODY /$/    { data -element lastModified $1 }
1209 /\n\n/ BODY END      {
1210                         begin element bodyOfDisplay
1211                         begin variant body iana "text/plain"
1212                         data -text $1
1213                         end record
1214                      }
1215 </verb></tscreen>
1216
1217 If Zebra is compiled with support for Tcl (Tool Command Language)
1218 enabled, the statements described above are supplemented with a complete
1219 scripting environment, including control structures (conditional
1220 expressions and loop constructs), and powerful string manipulation
1221 mechanisms for modifying the elements of a record. Tcl is a popular
1222 scripting environment, with several tutorials available both online
1223 and in hardcopy.
1224
1225 <it>NOTE: Tcl support is not currently available, but will be
1226 included with one of the next alpha or beta releases.</it>
1227
1228 <it>NOTE: Variant support is not currently available in the input
1229 filter, but will be included with one of the next alpha or beta
1230 releases.</it>
1231
1232 <sect1>Internal Representation<label id="internal-representation">
1233
1234 <p>
1235 When records are manipulated by the system, they're represented in a
1236 tree-structure, with data elements at the leaf nodes, and tags or
1237 variant components at the non-leaf nodes. The root-node identifies the
1238 schema that lends context to the tagging and structuring of the
1239 record. Imagine a simple record, consisting of a 'title' element and
1240 an 'author' element:
1241
1242 <tscreen><verb>
1243         TITLE     "Zen and the Art of Motorcycle Maintenance"
1244 ROOT 
1245         AUTHOR    "Robert Pirsig"
1246 </verb></tscreen>
1247
1248 A slightly more complex record would have the author element consist
1249 of two elements, a surname and a first name:
1250
1251 <tscreen><verb>
1252         TITLE     "Zen and the Art of Motorcycle Maintenance"
1253 ROOT  
1254                   FIRST-NAME "Robert"
1255         AUTHOR
1256                   SURNAME    "Pirsig"
1257 </verb></tscreen>
1258
1259 The root of the record will refer to the record schema that describes
1260 the structuring of this particular record. The schema defines the
1261 element tags (TITLE, FIRST-NAME, etc.) that may occur in the record, as
1262 well as the structuring (SURNAME should appear below AUTHOR, etc.). In
1263 addition, the schema establishes element set names that are used by
1264 the client to request a subset of the elements of a given record. The
1265 schema may also establish rules for converting the record to a
1266 different schema, by stating, for each element, a mapping to a
1267 different tag path.
1268
1269 <sect2>Tagged Elements
1270
1271 <p>
1272 A data element is characterized by its tag, and its position in the
1273 structure of the record. For instance, while the tag &dquot;telephone
1274 number&dquot; may be used different places in a record, we may need to
1275 distinguish between these occurrences, both for searching and
1276 presentation purposes. For instance, while the phone numbers for the
1277 &dquot;customer&dquot; and the &dquot;service provider&dquot; are both
1278 representatives for the same type of resource (a telephone number), it
1279 is essential that they be kept separate. The record schema provides
1280 the structure of the record, and names each data element (defined by
1281 the sequence of tags - the tag path - by which the element can be
1282 reached from the root of the record).
1283
1284 <sect2>Variants
1285
1286 <p>
1287 The children of a tag node may be either more tag nodes, a data node
1288 (possibly accompanied by tag nodes),
1289 or a tree of variant nodes. The children of  variant nodes are either
1290 more variant nodes or a data node (possibly accompanied by more
1291 variant nodes). Each leaf node, which is normally a
1292 data node, corresponds to a <it/variant form/ of the tagged element
1293 identified by the tag which parents the variant tree. The following
1294 title element occurs in two different languages:
1295
1296 <tscreen><verb>
1297       VARIANT LANG=ENG  "War and Peace"
1298 TITLE
1299       VARIANT LANG=DAN  "Krig og Fred"
1300 </verb></tscreen>
1301
1302 Which of the two elements are transmitted to the client by the server
1303 depends on the specifications provided by the client, if any.
1304
1305 In practice, each variant node is associated with a triple of class,
1306 type, value, corresponding to the variant mechanism of Z39.50.
1307
1308 <sect2>Data Elements
1309
1310 <p>
1311 Data nodes have no children (they are always leaf nodes in the record
1312 tree).
1313
1314 <it>NOTE: Documentation needs extension here about types of nodes - numerical,
1315 textual, etc., plus the various types of inclusion notes.</it>
1316
1317 <sect1>Configuring Your Data Model<label id="data-model">
1318
1319 <p>
1320 The following sections describe the configuration files that govern
1321 the internal management of data records. The system searches for the files
1322 in the directories specified by the <bf/profilePath/ setting in the
1323 <tt/zebra.cfg/ file.
1324
1325 <sect2>The Abstract Syntax
1326
1327 <p>
1328 The abstract syntax definition (also known as an Abstract Record
1329 Structure, or ARS) is the focal point of the
1330 record schema description. For a given schema, the ABS file may state any
1331 or all of the following:
1332
1333 <itemize>
1334 <item>The object identifier of the Z39.50 schema associated
1335 with the ARS, so that it can be referred to by the client.
1336
1337 <item>The attribute set (which can possibly be a compound of multiple
1338 sets) which applies in the profile. This is used when indexing and
1339 searching the records belonging to the given profile.
1340
1341 <item>The Tag set (again, this can consist of several different sets).
1342 This is used when reading the records from a file, to recognize the
1343 different tags, and when transmitting the record to the client -
1344 mapping the tags to their numerical representation, if they are
1345 known.
1346
1347 <item>The variant set which is used in the profile. This provides a
1348 vocabulary for specifying the <it/forms/ of data that appear inside
1349 the records.
1350
1351 <item>Element set names, which are a shorthand way for the client to
1352 ask for a subset of the data elements contained in a record. Element
1353 set names, in the retrieval module, are mapped to <it/element
1354 specifications/, which contain information equivalent to the
1355 <it/Espec-1/ syntax of Z39.50.
1356
1357 <item>Map tables, which may specify mappings to <it/other/ database
1358 profiles, if desired.
1359
1360 <item>Possibly, a set of rules describing the mapping of elements to a
1361 MARC representation.
1362
1363 <item>A list of element descriptions (this is the actual ARS of the
1364 schema, in Z39.50 terms), which lists the ways in which the various
1365 tags can be used and organized hierarchically.
1366 </itemize>
1367
1368 Several of the entries above simply refer to other files, which
1369 describe the given objects.
1370
1371 <sect2>The Configuration Files
1372
1373 <p>
1374 This section describes the syntax and use of the various tables which
1375 are used by the retrieval module.
1376
1377 The number of different file types may appear daunting at first, but
1378 each type corresponds fairly clearly to a single aspect of the Z39.50
1379 retrieval facilities. Further, the average database administrator,
1380 who is simply reusing an existing profile for which tables already
1381 exist, shouldn't have to worry too much about the contents of these tables.
1382
1383 Generally, the files are simple ASCII files, which can be maintained
1384 using any text editor. Blank lines, and lines beginning with a (&num;) are
1385 ignored. Any characters on a line followed by a (&num;) are also ignored.
1386 All other
1387 lines contain <it/directives/, which provide some setting or value
1388 to the system. Generally, settings are characterized by a single
1389 keyword, identifying the setting, followed by a number of parameters.
1390 Some settings are repeatable (r), while others may occur only once in a
1391 file. Some settings are optional (o), whicle others again are
1392 mandatory (m).
1393
1394 <sect2>The Abstract Syntax (.abs) Files
1395
1396 <p>
1397 The name of this file type is slightly misleading in Z39.50 terms,
1398 since, apart from the actual abstract syntax of the profile, it also
1399 includes most of the other definitions that go into a database
1400 profile.
1401
1402 When a record in the canonical, SGML-like format is read from a file
1403 or from the database, the first tag of the file should reference the
1404 profile that governs the layout of the record. If the first tag of the
1405 record is, say, <tt>&lt;gils&gt;</tt>, the system will look for the profile
1406 definition in the file <tt/gils.abs/. Profile definitions are cached,
1407 so they only have to be read once during the lifespan of the current
1408 process. 
1409
1410 When writing your own input filters, the <bf/record-begin/ command
1411 introduces the profile, and should always be called first thing when
1412 introducing a new record.
1413
1414 The file may contain the following directives:
1415
1416 <descrip>
1417 <tag>name <it/symbolic-name/</tag> (m) This provides a shorthand name or
1418 description for the profile. Mostly useful for diagnostic purposes.
1419
1420 <tag>reference <it/OID-name/</tag> (m) The reference name of the OID for
1421 the profile. The reference names can be found in the <bf/util/
1422 module of <bf/YAZ/.
1423
1424 <tag>attset <it/filename/</tag> (m) The attribute set that is used for
1425 indexing and searching records belonging to this profile.
1426
1427 <tag>tagset <it/filename/</tag> (o) The tag set (if any) that describe
1428 that fields of the records.
1429
1430 <tag>varset <it/filename/</tag> (o) The variant set used in the profile.
1431
1432 <tag>maptab <it/filename/</tag> (o,r) This points to a
1433 conversion table that might be used if the client asks for the record
1434 in a different schema from the native one.
1435
1436 <tag>marc <it/filename/</tag> (o) Points to a file containing parameters
1437 for representing the record contents in the ISO2709 syntax. Read the
1438 description of the MARC representation facility below.
1439
1440 <tag>esetname <it/name filename/</tag> (o,r) Associates the
1441 given element set name with an element selection file. If an (@) is
1442 given in place of the filename, this corresponds to a null mapping for
1443 the given element set name.
1444
1445 <tag>elm <it/path name attribute/</tag> (o,r) Adds an element
1446 to the abstract record syntax of the schema. The <it/path/ follows the
1447 syntax which is suggested by the Z39.50 document - that is, a sequence
1448 of tags separated by slashes (/). Each tag is given as a
1449 comma-separated pair of tag type and -value surrounded by parenthesis.
1450 The <it/name/ is the name of the element, and the <it/attribute/
1451 specifies what attribute to use when indexing the element. A ! in
1452 place of the attribute name is equivalent to specifying an attribute
1453 name identical to the element name. A - in place of the attribute name
1454 specifies that no indexing is to take place for the given element.
1455 </descrip>
1456
1457 <it>
1458 NOTE: The mechanism for controlling indexing is not adequate for
1459 complex databases, and will probably be moved into a separate
1460 configuration table eventually.
1461 </it>
1462
1463 The following is an excerpt from the abstract syntax file for the GILS
1464 profile.
1465
1466 <tscreen><verb>
1467 name gils
1468 reference GILS-schema
1469 attset gils.att
1470 tagset gils.tag
1471 varset var1.var
1472
1473 maptab gils-usmarc.map
1474
1475 # Element set names
1476
1477 esetname VARIANT gils-variant.est  # for WAIS-compliance
1478 esetname B gils-b.est
1479 esetname G gils-g.est
1480 esetname F @
1481
1482 elm (1,10)              rank                        -
1483 elm (1,12)              url                         -
1484 elm (1,14)              localControlNumber     Local-number
1485 elm (1,16)              dateOfLastModification Date/time-last-modified
1486 elm (2,1)               Title                       !
1487 elm (4,1)               controlIdentifier      Identifier-standard
1488 elm (2,6)               abstract               Abstract
1489 elm (4,51)              purpose                     !
1490 elm (4,52)              originator                  - 
1491 elm (4,53)              accessConstraints           !
1492 elm (4,54)              useConstraints              !
1493 elm (4,70)              availability                -
1494 elm (4,70)/(4,90)       distributor                 -
1495 elm (4,70)/(4,90)/(2,7) distributorName             !
1496 elm (4,70)/(4,90)/(2,10 distributorOrganization     !
1497 elm (4,70)/(4,90)/(4,2) distributorStreetAddress    !
1498 elm (4,70)/(4,90)/(4,3) distributorCity             !
1499 </verb></tscreen>
1500
1501 <sect2>The Attribute Set (.att) Files<label id="attset-files">
1502
1503 <p>
1504 This file type describes the <bf/Use/ elements of an attribute set.
1505 It contains the following directives. 
1506
1507 <descrip>
1508
1509 <tag>name <it/symbolic-name/</tag> (m) This provides a shorthand name or
1510 description for the attribute set. Mostly useful for diagnostic purposes.
1511
1512 <tag>reference <it/OID-name/</tag> (m) The reference name of the OID for
1513 the attribute set. The reference names can be found in the <bf/util/
1514 module of <bf/YAZ/.
1515
1516 <tag>ordinal <it/integer/</tag> (m) This value will be used to represent the
1517 attribute set in the index. Care should be taken that each attribute
1518 set has a unique ordinal value.
1519
1520 <tag>include <it/filename/</tag> (o,r) This directive is used to
1521 include another attribute set as a part of the current one. This is
1522 used when a new attribute set is defined as an extension to another
1523 set. For instance, many new attribute sets are defined as extensions
1524 to the <bf/bib-1/ set. This is an important feature of the retrieval
1525 system of Z39.50, as it ensures the highest possible level of
1526 interoperability, as those access points of your database which are
1527 derived from the external set (say, bib-1) can be used even by clients
1528 who are unaware of the new set.
1529
1530 <tag>att <it/att-value att-name &lsqb;local-value&rsqb;/</tag> (o,r) This
1531 repeatable directive introduces a new attribute to the set. The
1532 attribute value is stored in the index (unless a <it/local-value/ is
1533 given, in which case this is stored). The name is used to refer to the
1534 attribute from the <it/abstract syntax/. </descrip>
1535
1536 This is an excerpt from the GILS attribute set definition. Notice how
1537 the file describing the <it/bib-1/ attribute set is referenced.
1538
1539 <tscreen><verb>
1540 name gils
1541 reference GILS-attset
1542 include bib1.att
1543 ordinal 2
1544
1545 att 2001                distributorName
1546 att 2002                indexTermsControlled
1547 att 2003                purpose
1548 att 2004                accessConstraints
1549 att 2005                useConstraints
1550 </verb></tscreen>
1551
1552 <sect2>The Tag Set (.tag) Files
1553
1554 <p>
1555 This file type defines the tagset of the profile, possibly by
1556 referencing other tag sets (most tag sets, for instance, will include
1557 tagsetG and tagsetM from the Z39.50 specification. The file may
1558 contain the following directives.
1559
1560 <descrip>
1561 <tag>name <it/symbolic-name/</tag> (m) This provides a shorthand name or
1562 description for the tag set. Mostly useful for diagnostic purposes.
1563
1564 <tag>reference <it/OID-name/</tag> (o) The reference name of the OID for
1565 the tag set. The reference names can be found in the <bf/util/
1566 module of <bf/YAZ/. The directive is optional, since not all tag sets
1567 are registered outside of their schema.
1568
1569 <tag>type <it/integer/</tag> (m) The type number of the tag within the schema
1570 profile.
1571
1572 <tag>include <it/filename/</tag> (o,r) This directive is used
1573 to include the definitions of other tag sets into the current one.
1574
1575 <tag>tag <it/number names type/</tag> (o,r) Introduces a new
1576 tag to the set. The <it/number/ is the tag number as used in the protocol
1577 (there is currently no mechanism for specifying string tags at this
1578 point, but this would be quick work to add). The <it/names/ parameter
1579 is a list of names by which the tag should be recognized in the input
1580 file format. The names should be separated by slashes (/). The
1581 <it/type/ is th recommended datatype of the tag. It should be one of
1582 the following:
1583 <itemize>
1584 <item>structured
1585 <item>string
1586 <item>numeric
1587 <item>bool
1588 <item>oid
1589 <item>generalizedtime
1590 <item>intunit
1591 <item>int
1592 <item>octetstring
1593 <item>null
1594 </itemize>
1595 </descrip>
1596
1597 The following is an excerpt from the TagsetG definition file.
1598
1599 <tscreen><verb>
1600 name tagsetg
1601 reference TagsetG
1602 type 2
1603
1604 tag     1       title           string
1605 tag     2       author          string
1606 tag     3       publicationPlace string
1607 tag     4       publicationDate string
1608 tag     5       documentId      string
1609 tag     6       abstract        string
1610 tag     7       name            string
1611 tag     8       date            generalizedtime
1612 tag     9       bodyOfDisplay   string
1613 tag     10      organization    string
1614 </verb></tscreen>
1615
1616 <sect2>The Variant Set (.var) Files<label id="variant-set">
1617
1618 <p>
1619 The variant set file is a straightforward representation of the
1620 variant set definitions associated with the protocol. At present, only
1621 the <it/Variant-1/ set is known.
1622
1623 These are the directives allowed in the file.
1624
1625 <descrip>
1626 <tag>name <it/symbolic-name/</tag> (m) This provides a shorthand name or
1627 description for the variant set. Mostly useful for diagnostic purposes.
1628
1629 <tag>reference <it/OID-name/</tag> (o) The reference name of the OID for
1630 the variant set, if one is required. The reference names can be found
1631 in the <bf/util/ module of <bf/YAZ/.
1632
1633 <tag>class <it/integer class-name/</tag> (m,r) Introduces a new
1634 class to the variant set.
1635
1636 <tag>type <it/integer type-name datatype/</tag> (m,r) Addes a
1637 new type to the current class (the one introduced by the most recent
1638 <bf/class/ directive). The type names belong to the same name space as
1639 the one used in the tag set definition file.
1640 </descrip>
1641
1642 The following is an excerpt from the file describing the variant set
1643 <it/Variant-1/.
1644
1645 <tscreen><verb>
1646 name variant-1
1647 reference Variant-1
1648
1649 class 1 variantId
1650
1651   type  1       variantId               octetstring
1652
1653 class 2 body
1654
1655   type  1       iana                    string
1656   type  2       z39.50                  string
1657   type  3       other                   string
1658 </verb></tscreen>
1659
1660 <sect2>The Element Set (.est) Files
1661
1662 <p>
1663 The element set specification files describe a selection of a subset
1664 of the elements of a database record. The element selection mechanism
1665 is equivalent to the one supplied by the <it/Espec-1/ syntax of the
1666 Z39.50 specification. In fact, the internal representation of an
1667 element set specification is identical to the <it/Espec-1/ structure,
1668 and we'll refer you to the description of that structure for most of
1669 the detailed semantics of the directives below.
1670
1671 <it>
1672 NOTE: Not all of the Espec-1 functionality has been implemented yet.
1673 The fields that are mentioned below all work as expected, unless
1674 otherwise is noted.
1675 </it>
1676
1677 The directives available in the element set file are as follows:
1678
1679 <descrip>
1680 <tag>defaultVariantSetId <it/OID-name/</tag> (o) If variants are used in
1681 the following, this should provide the name of the variantset used
1682 (it's not currently possible to specify a different set in the
1683 individual variant request). In almost all cases (certainly all
1684 profiles known to us), the name <tt/Variant-1/ should be given here.
1685
1686 <tag>defaultVariantRequest <it/variant-request/</tag> (o) This directive
1687 provides a default variant request for
1688 use when the individual element requests (see below) do not contain a
1689 variant request. Variant requests consist of a blank-separated list of
1690 variant components. A variant compont is a comma-separated,
1691 parenthesized triple of variant class, type, and value (the two former
1692 values being represented as integers). The value can currently only be
1693 entered as a string (this will change to depend on the definition of
1694 the variant in question). The special value (@) is interpreted as a
1695 null value, however.
1696
1697 <tag>simpleElement <it/path &lsqb;'variant' variant-request&rsqb;/</tag>
1698 (o,r) This corresponds to a simple element request in <it/Espec-1/. The
1699 path consists of a sequence of tag-selectors, where each of these can
1700 consist of either:
1701
1702 <itemize>
1703 <item>A simple tag, consisting of a comma-separated type-value pair in
1704 parenthesis, possibly followed by a colon (:) followed by an
1705 occurrences-specification (see below). The tag-value can be a number
1706 or a string. If the first character is an apostrophe ('), this forces
1707 the value to be interpreted as a string, even if it appears to be numerical.
1708
1709 <item>A WildThing, represented as a question mark (?), possibly
1710 followed by a colon (:) followed by an occurrences specification (see
1711 below).
1712
1713 <item>A WildPath, represented as an asterisk (*). Note that the last
1714 element of the path should not be a wildPath (wildpaths don't work in
1715 this version).
1716 </itemize>
1717
1718 The occurrences-specification can be either the string <tt/all/, the
1719 string <tt/last/, or an explicit value-range. The value-range is
1720 represented as an integer (the starting point), possibly followed by a
1721 plus (+) and a second integer (the number of elements, default being
1722 one).
1723
1724 The variant-request has the same syntax as the defaultVariantRequest
1725 above. Note that it may sometimes be useful to give an empty variant
1726 request, simply to disable the default for a specific set of fields
1727 (we aren't certain if this is proper <it/Espec-1/, but it works in
1728 this implementation).
1729 </descrip>
1730
1731 The following is an example of an element specification belonging to
1732 the GILS profile.
1733
1734 <tscreen><verb>
1735 simpleelement (1,10)
1736 simpleelement (1,12)
1737 simpleelement (2,1)
1738 simpleelement (1,14)
1739 simpleelement (4,1)
1740 simpleelement (4,52)
1741 </verb></tscreen>
1742
1743 <sect2>The Schema Mapping (.map) Files<label id="schema-mapping">
1744
1745 <p>
1746 Sometimes, the client might want to receive a database record in
1747 a schema that differs from the native schema of the record. For
1748 instance, a client might only know how to process WAIS records, while
1749 the database record is represented in a more specific schema, such as
1750 GILS. In this module, a mapping of data to one of the MARC formats is
1751 also thought of as a schema mapping (mapping the elements of the
1752 record into fields consistent with the given MARC specification, prior
1753 to actually converting the data to the ISO2709). This use of the
1754 object identifier for USMARC as a schema identifier represents an
1755 overloading of the OID which might not be entirely proper. However,
1756 it represents the dual role of schema and record syntax which
1757 is assumed by the MARC family in Z39.50.
1758
1759 <it>
1760 NOTE: The schema-mapping functions are so far limited to a
1761 straightforward mapping of elements. This should be extended with
1762 mechanisms for conversions of the element contents, and conditional
1763 mappings of elements based on the record contents.
1764 </it>
1765
1766 These are the directives of the schema mapping file format:
1767
1768 <descrip>
1769 <tag>targetName <it/name/</tag> (m) A symbolic name for the target schema
1770 of the table. Useful mostly for diagnostic purposes.
1771
1772 <tag>targetRef <it/OID-name/</tag> (m) An OID name for the target schema.
1773 This is used, for instance, by a server receiving a request to present
1774 a record in a different schema from the native one. The name, again,
1775 is found in the <bf/oid/ module of <bf/YAZ/.
1776
1777 <tag>map <it/element-name target-path/</tag> (o,r) Adds
1778 an element mapping rule to the table.
1779 </descrip>
1780
1781 <sect2>The MARC (ISO2709) Representation (.mar) Files
1782
1783 <p>
1784 This file provides rules for representing a record in the ISO2709
1785 format. The rules pertain mostly to the values of the constant-length
1786 header of the record.
1787
1788 <it>NOTE: This will be described better. We're in the process of
1789 re-evaluating and most likely changing the way that MARC records are
1790 handled by the system.</it>
1791
1792 <sect1>Exchange Formats
1793
1794 <p>
1795 Converting records from the internal structure to en exchange format
1796 is largely an automatic process. Currently, the following exchange
1797 formats are supported:
1798
1799 <itemize>
1800 <item>GRS-1. The internal representation is based on GRS-1, so the
1801 conversion here is straightforward. The system will create
1802 applied variant and supported variant lists as required, if a record
1803 contains variant information.
1804
1805 <item>SUTRS. Again, the mapping is fairly straighforward. Indentation
1806 is used to show the hierarchical structure of the record.
1807
1808 <item>ISO2709-based formats (USMARC, etc.). Only records with a
1809 two-level structure (corresponding to fields and subfields) can be
1810 directly mapped to ISO2709. For records with a different structuring
1811 (eg., GILS), the representation in a structure like USMARC involves a
1812 schema-mapping (see section <ref id="schema-mapping" name="Schema
1813 Mapping">), to an &dquot;implied&dquot; USMARC schema (implied,
1814 because there is no formal schema which specifies the use of the
1815 USMARC fields outside of ISO2709). The resultant, two-level record is
1816 then mapped directly from the internal representation to ISO2709. See
1817 the GILS schema definition files for a detailed example of this
1818 approach.
1819
1820 <item>Explain. This representation is only available for records
1821 belonging to the Explain schema.
1822
1823 </itemize>
1824
1825 <sect>License
1826
1827 <p>
1828 Copyright &copy; 1995, Index Data.
1829
1830 All rights reserved.
1831
1832 Use and redistribution in source or binary form, with or without
1833 modification, of any or all of this software and documentation is
1834 permitted, provided that the following conditions are met:
1835
1836 1. This copyright and permission notice appear with all copies of the
1837 software and its documentation. Notices of copyright or attribution
1838 which appear at the beginning of any file must remain unchanged.
1839
1840 2. The names of Index Data or the individual authors may not be used to
1841 endorse or promote products derived from this software without specific
1842 prior written permission.
1843
1844 3. Source code or binary versions of this software and its
1845 documentation may be used freely in not-for-profit applications. For
1846 profit applications - such as providing for-pay database services,
1847 marketing a product based in whole or in part on this software or its
1848 documentation, or generally distributing this software or its
1849 documentation under a different license - requires a commercial
1850 license from Index Data. The software may be installed and used for
1851 evaluation purposes in conjunction with a commercial application for a
1852 trial period of no more than 60 days.
1853
1854 THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
1855 EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
1856 WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
1857 IN NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
1858 INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
1859 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR
1860 NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
1861 LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
1862 OF THIS SOFTWARE.
1863
1864 <sect>About Index Data and the Zebra Server
1865
1866 <p>
1867 Index Data is a consulting and software-development enterprise that
1868 specialises in library and information management systems. Our
1869 interests and expertise span a broad range of related fields, and one
1870 of our primary, long-term objectives is the development of a powerful
1871 information management
1872 system with open network interfaces and hypermedia capabilities.
1873
1874 We make this software available free of charge for not-for-profit
1875 purposes, as a service to the networking community, and to further
1876 the development and use of quality software for open network
1877 communication.
1878
1879 If you like this software, and would like to use all or part of it in
1880 a commercial product, or to provide a commercial database service,
1881 please contact us to discuss the details. We'll be happy to answer
1882 questions about the software, and about our services in general. If
1883 you have specific requirements to the software, we'll be glad to offer
1884 our advice - and if you need to adapt the software to a special
1885 purpose, our consulting services and expert knowledge of the software
1886 is available to you at favorable rates.
1887
1888 <tscreen>
1889 Index Data&nl
1890 Ryesgade 3&nl
1891 DK-2200 K&oslash;benhavn N&nl
1892 </tscreen>
1893
1894 <p>
1895 <tscreen><verb>
1896 Phone: +45 3536 3672
1897 Fax  : +45 3536 0449
1898 Email: info@index.ping.dk
1899 </verb></tscreen>
1900
1901 The <it>Random House College Dictionary</it>, 1975 edition
1902 offers this definition of the 
1903 word &dquot;Zebra&dquot;:
1904
1905 <it>
1906 Zebra, n., any of several horselike, African mammals of the genus Equus,
1907 having a characteristic pattern of black or dark-brown stripes on
1908 a whitish background.
1909 </it>
1910
1911 </article>